Я придумал следующий метод:
function isSequential(array $list): bool
{
$i = 0;
$count = count($list);
while (array_key_exists($i, $list)) {
$i += 1;
if ($i === $count) {
return true;
}
}
return false;
}
var_dump(isSequential(array())); // false
var_dump(isSequential(array('a', 'b', 'c'))); // true
var_dump(isSequential(array("0" => 'a', "1" => 'b', "2" => 'c'))); // true
var_dump(isSequential(array("1" => 'a', "0" => 'b', "2" => 'c'))); // true
var_dump(isSequential(array("1a" => 'a', "0b" => 'b', "2c" => 'c'))); // false
var_dump(isSequential(array("a" => 'a', "b" => 'b', "c" => 'c'))); // false
* Обратите внимание, что пустой массив не считается последовательным массивом, но я думаю, что все в порядке, поскольку пустые массивы похожи на 0 - не важно, плюс это или минус, он пуст.
Вот преимущества этого метода по сравнению с некоторыми из перечисленных выше:
- Это не связано с копированием массивов (кто-то упомянул в этой сущности https://gist.github.com/Thinkscape/1965669, что
array_values
не включает копирование - что! ?? Конечно, это происходит - как будет видно ниже )
- Это быстрее для больших массивов и одновременно более дружественной памяти
Я использовал бенчмарк, любезно предоставленный Артуром Бодера , где я изменил один из массивов на 1M элементов (array_fill(0, 1000000, uniqid()), // big numeric array
).
Вот результаты для 100 итераций:
PHP 7.1.16 (cli) (built: Mar 31 2018 02:59:59) ( NTS )
Initial memory: 32.42 MB
Testing my_method (isset check) - 100 iterations
Total time: 2.57942 s
Total memory: 32.48 MB
Testing method3 (array_filter of keys) - 100 iterations
Total time: 5.10964 s
Total memory: 64.42 MB
Testing method1 (array_values check) - 100 iterations
Total time: 3.07591 s
Total memory: 64.42 MB
Testing method2 (array_keys comparison) - 100 iterations
Total time: 5.62937 s
Total memory: 96.43 MB
* Методы упорядочены в зависимости от их потребления памяти
** Я использовал echo " Total memory: " . number_format(memory_get_peak_usage()/1024/1024, 2) . " MB\n";
для отображения использования памяти