Поиск первого доступного идентификатора из массива

Учитывая такой массив:

Array => ( [0] => 1, [1] => 2, [2] => 3, [3] => 5, [4] => 6 ) 

Самый простой способ найти первый «доступный» идентификатор в этом массиве – то есть первое значение в последовательности [1,2,3...n] которое не существует в массиве? В этом случае правильным ответом будет 4 .

Я могу сделать это, используя некоторые циклы или сортировки с временными переменными, но это немного грязно, поэтому мне интересно узнать, может ли кто-нибудь придумать «умное» решение.

Solutions Collecting From Web of "Поиск первого доступного идентификатора из массива"

Мои навыки 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);