Есть массив такого содержания:
array (
0 => '1',
1 => '2',
2 => '3',
3 => '4',
4 => '5',
5 => '6',
6 => '7',
7 => '8',
8 => '9',
9 => '11',
10 => '12',
11 => '13',
)
Нужно найти есть ли пропущенное значение в нем, например в этом, после 9 сразу идет 11 , то есть пропущено значение 10
Буду благодарен за полезную информацию.
Если размер массива достаточно большой, а предполагаемое число пропущенных элементов не велико, можно еще и такой вариант.
$data = [1,2,5,6,9,11];
$prev = current($data);
$result = array_reduce($data, function($c, $item) use (&$prev){
if($item - $prev > 1){
$c = array_merge($c, range($prev + 1, $item - 1));
}
$prev = $item;
return $c;
}, []);
А если специфика задачи такова, что у нас очень большой массив и получается очень много пропущенных значений (и не очень большом числе самих пропущенных интервалов), что использование функции range
тратит не оправдано много памяти, то как по классическому примеру из справки по использованию генераторов можем сделать следующее:
$result = function($data){
$prev = current($data);
$ranges = array_reduce($data, function($c, $item) use (&$prev){
if($item - $prev > 1) $c[] = [$prev+1, $item -1];
$prev = $item;
return $c;
}, []);
foreach($ranges as list($l, $h)){
while($l <= $h) yield $l++;
}
};
foreach($result($data) as $x) echo $x, "\n";
в этом случае память будет тратится только на хранение пар значений, обозначающих края пропущенных отрезков.
хотелось бы более продвинутого решения)
$arr = [
0 => '1',
1 => '2',
2 => '3',
3 => '4',
4 => '5',
5 => '6',
6 => '7',
7 => '8',
8 => '9',
9 => '11',
10 => '12',
11 => '13'
];
$temp = range(reset($arr), end($arr));
$diff = array_diff($temp, $arr);
print_r($diff);
Не самое элегантное решение, но рабочее.
$arr = [1, 2, 5, 6, 7, 9, 11];
$missedNumbers = [];
foreach ($arr as $id => $number) {
if (!isset($arr[$id + 1])) {
continue;
}
if ($arr[$id + 1] - $number !== 1) {
for ($i = 1; $i < $arr[$id + 1] - $number; $i++) {
$missedNumbers[] = $arr[$id + 1] - $i;
}
}
}
В цикле for находим недостающие числа.
$missedNumbers содержит следущее:
Array
(
[0] => 4
[1] => 3
[2] => 8
[3] => 10
)
Мне нужно было найти первое пропущенное значение массива. Хотя в вопросе не указано именно первое, но и не указано, что все пропущенные.
Если нужно искать все пропущенные и оптимизировать расход памяти, то уже есть решение от @teran. Только не забудьте про sort()
вначале, если надо пройтись по-порядку. Я его протестировал - отлично работает.
В общем, сделал так:
function missedVal($A) {
sort($A);
foreach ($A as $key => $value) {
if ($key!=0 && $value!=$A[$key-1] && $A[$key-1]!=$value-1) {
return $A[$key-1]+1;
break;
}
}
}
$A = [1, 2, 4, 1, 2, 7, 9, 3];
echo missedVal($A);
Возвращает - 5, func дошла до первого пропущенного и закончила работу.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
У меня в js коде формируется массив dataArr вида [0,4,5,4,7,4,5,27]
Существует ли библиотека JSON, в которой можно обращаться к элементам с помощью []