Учитывая такой массив:
Array => ( [0] => 1, [1] => 2, [2] => 3, [3] => 5, [4] => 6 )
Самый простой способ найти первый «доступный» идентификатор в этом массиве – то есть первое значение в последовательности [1,2,3...n]
которое не существует в массиве? В этом случае правильным ответом будет 4
.
Я могу сделать это, используя некоторые циклы или сортировки с временными переменными, но это немного грязно, поэтому мне интересно узнать, может ли кто-нибудь придумать «умное» решение.
Мои навыки PHP немного ржавые, но вы не можете использовать range
и array_diff
:
$missing = array_diff(range(1, end($myArray)+ 1), $myArray); echo $missing[0];
Обновлено с исправлениями Тату Улмана (я сказал, что мой PHP был ржавым ;-))
Я не могу ничего придумать, кроме сортировки массива и прохождения через него, поиска отверстий.
Может быть, что-то вроде:
sort($array); $next_available = array_shift($array); foreach($array as $_k) { ++$next_available; if($_k > $next_available) { break; } } echo "Next available index: {$next_available}";
Я не считаю, что это менее беспорядочно, чем какой-то цикл, но здесь идет мой надуманный пример:
sort( $array ); $range = range( reset( $array ), end( $array ) ); $diff = array_diff( $range, $array ); $result = null != ( $result = array_shift( $diff ) ) ? $result : end( $array ) + 1;
Это немного волшебство, но трюк:
$values = array_values($id_array); $values[] = max($values) + 1; $combined = array_values(array_flip($values) + array_keys($values)); $missing = isset($combined[count($values) + 1]) ? $combined[count($values) + 1] : end($values);
Преимущество этого в том, что он значительно быстрее. Проблема с использованием range()
заключается в том, что один большой ключ в малом массиве сделает array_diff()
очень медленным. Кроме того, это приведет к возврату следующего ключа, если в идентификаторах нет пробелов (или вы можете изменить конечный результат end($values)
на false
, если это то, что вы бы предпочли).
Несмотря на умность, он все еще медленнее, чем просто повторение массива. Но array_diff()
(даже без range()
) будет намного медленнее.
если ваш массив использует только числовой ключ и без отверстия, вы можете сделать $next_id = count($your_array)
если есть отверстия, вы можете попробовать
$keys = array_keys($your_array); rsort($keys); $next_id = empty($keys)?0:($keys[0]+1);