Есть массив такого содержания:
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 дошла до первого пропущенного и закончила работу.
Перевод документов на английский язык: Важность и ключевые аспекты
Какие существуют виды рекламных бордов и как выбрать подходящий?
Аренда удаленного сервера: цены, провайдеры и условия. Руководство для начинающих
У меня в js коде формируется массив dataArr вида [0,4,5,4,7,4,5,27]
Существует ли библиотека JSON, в которой можно обращаться к элементам с помощью []