Как проверить, является ли массив в PHP ассоциативным или последовательным (индексированным)?
Основной способ: проверка ключей на последовательность
В PHP нет единой встроенной функции для проверки типа массива, но задачу можно решить несколькими способами. Самый надёжный — проверить, что все ключи являются целыми числами и образуют строгую последовательность от 0 до count($array)-1.
Вот простая и эффективная функция:
function isSequentialArray(array $array): bool {
if (empty($array)) {
return true; // Пустой массив считаем последовательным
}
return array_keys($array) === range(0, count($array) - 1);
}
Разберём, как это работает:
array_keys($array)— возвращает все ключи массива.range(0, count($array) - 1)— генерирует эталонный массив [0, 1, 2, ..., N-1].- Оператор
===сравнивает не только значения, но и типы (строгое сравнение).
Примеры использования:
$arr1 = ['a', 'b', 'c'];
var_dump(isSequentialArray($arr1)); // true
$arr2 = ['name' => 'John', 'age' => 30];
var_dump(isSequentialArray($arr2)); // false
$arr3 = [0 => 'x', 1 => 'y', 3 => 'z'];
var_dump(isSequentialArray($arr3)); // false (пропущен ключ 2)
$arr4 = ['a', 'b', 'c' => 'd'];
var_dump(isSequentialArray($arr4)); // false (есть строковый ключ)
$arr5 = [5 => 'start', 6 => 'end'];
var_dump(isSequentialArray($arr5)); // false (начинается не с 0)
$empty = [];
var_dump(isSequentialArray($empty)); // true (пустой массив)
Более производительный вариант для больших массивов
Если массив содержит миллионы элементов, создание двух массивов через array_keys() и range() может быть затратным. Вот альтернатива без копирования ключей:
function isSequentialArray(array $array): bool {
$expectedKey = 0;
foreach ($array as $key => $value) {
if ($key !== $expectedKey) {
return false;
}
$expectedKey++;
}
return true;
}
Этот вариант проходит по массиву один раз и проверяет каждый ключ на лету. Он быстрее и использует меньше памяти.
Дополнительные нюансы
Обратите внимание: в PHP массивы могут содержать элементы с ключом null или пустой строкой. Функции выше корректно обработают такие случаи:
- Ключ
nullбудет преобразован в пустую строку — это не целое число, поэтому массив будет считаться ассоциативным. - Если массив начинается с ключа 0, но потом идёт ключ 'a' — функция вернёт
false.
Если вам нужно просто узнать, есть ли в массиве строковые ключи (ассоциативность в широком смысле), можно использовать такой подход:
function isAssociative(array $array): bool {
if (empty($array)) {
return false;
}
foreach ($array as $key => $value) {
if (!is_int($key)) {
return true;
}
}
return false;
}
Но помните: числовой массив с пропусками (как [0 => 'a', 2 => 'b']) не будет считаться ассоциативным в этой функции, хотя и не является последовательным. Выбирайте подход в зависимости от вашей задачи.
Использование array_values() для сброса ключей
Ещё один простой способ — сравнить исходный массив с его "переиндексированной" версией. Если после применения array_values() массив не изменился, значит, он был последовательным.
function isSequentialArray(array $array): bool {
return $array === array_values($array);
}
Как это работает: array_values() возвращает массив с числовыми ключами от 0, сбрасывая любые существующие ключи. Затем строгое сравнение === проверяет, совпадают ли исходный и новый массивы. Если ключи уже были последовательными — массивы будут идентичны.
Пример:
$arr1 = ['a', 'b', 'c']; // true
$arr2 = ['name' => 'John']; // false (ключи изменятся)
$arr3 = [0 => 'x', 1 => 'y', 3 => 'z']; // false (пропуск)
$arr4 = [5 => 'start']; // false (начинается с 5)
Когда это может быть полезно
Этот метод хорош, когда вам нужно просто проверить, можно ли безопасно обращаться к элементам по числовому индексу без риска получить unexpected. Например, перед передачей массива в функцию, ожидающую список (list).
Недостаток: для больших массивов array_values() создаёт копию, что увеличивает потребление памяти. Для критичных по производительности мест лучше использовать итеративный подход из первого ответа.
Ответов пока нет.
Войдите чтобы оставить ответ
Блоги