Как перенумеровать ключи массива в PHP (reset keys)
Сброс ключей массива в PHP: обзор методов
В PHP при работе с массивами часто возникает потребность перенумеровать ключи после удаления элементов или фильтрации. Функции вроде array_filter или array_slice сохраняют исходные ключи, что может приводить к неожиданным разрывам в последовательности. Сброс ключей (reset keys) позволяет сделать массив последовательным, начиная с нуля.
Как проще всего перенумеровать ключи массива с нуля?
Наиболее эффективный метод - встроенная функция array_values(). Она возвращает новый массив, содержащий все значения исходного массива, с числовыми ключами, начинающимися с 0.
$arr = ['a' => 1, 'b' => 2, 'c' => 3];
$reset = array_values($arr);
print_r($reset);Php reset keys (сброс ключей массива в php)
Array
(
[0] => 1
[1] => 2
[2] => 3
)
Функция работает с любыми типами массивов: ассоциативными, смешанными и с пропущенными числовыми ключами. Она не изменяет исходный массив, а создаёт новый. Это идеальное решение для большинства задач.
Проблема: array_values() сбрасывает только ключи первого уровня. Для многомерных массивов потребуется рекурсивный подход. Типичная ошибка - попытка использовать array_values на вложенном массиве без учёта вложенности.
Решение: для многомерных массивов применить рекурсивную функцию или комбинацию array_map с array_values для каждого внутреннего массива.
Как сбросить ключи с помощью цикла foreach?
Если нужно выполнить дополнительные преобразования во время переиндексации, можно использовать классический цикл.
$arr = ['x' => 10, 'y' => 20, 'z' => 30];
$newArr = [];
foreach ($arr as $value) {
$newArr[] = $value;
}
print_r($newArr);
Array
(
[0] => 10
[1] => 20
[2] => 30
)
Этот вариант даёт полный контроль над процессом, но требует больше кода. Подходит, когда нужно отфильтровывать или изменять значения по ходу.
Проблема: если исходный массив имеет строковые ключи, цикл foreach игнорирует их и берёт только значения. Это ожидаемо. Но если массив содержит вложенность, то потребуется рекурсивная обработка.
Как сделать сброс ключей без потери исходного порядка с помощью array_map?
Функция array_map с тождественной callback-функцией возвращает массив, перенумерованный с нуля.
$arr = ['a' => 1, 'b' => 2, 'c' => 3];
$reset = array_map(function($val) { return $val; }, $arr);
print_r($reset);
Array
(
[0] => 1
[1] => 2
[2] => 3
)
Этот метод аналогичен array_values, но может быть полезен, когда требуется изменить значения перед сбросом ключей (например, применить преобразование).
Проблема: array_map создаёт новый массив, но его производительность чуть ниже, чем у array_values, из-за вызова callback-функции для каждого элемента. Для больших массивов это может быть заметно.
Как сбросить ключи, отсортировав массив по значению (побочный эффект)?
Функция sort() переиндексирует массив, но при этом сортирует значения по возрастанию. Если сортировка не нужна, это приведёт к нежелательному изменению порядка.
$arr = ['c' => 3, 'a' => 1, 'b' => 2];
sort($arr);
print_r($arr);
Array
(
[0] => 1
[1] => 2
[2] => 3
)
Этот метод следует применять только тогда, когда требуется одновременно отсортировать массив и сбросить ключи. Если порядок важен, лучше отказаться от sort().
Проблема: неосознанное использование sort() вместо array_values может испортить данные, так как массив будет отсортирован. Ошибка часто возникает у новичков, которые ожидают только переиндексации.
Как сбросить ключи с помощью array_combine и range?
Можно вручную создать массив ключей через range() и объединить с исходными значениями.
$arr = ['x' => 10, 'y' => 20];
$keys = range(0, count($arr) - 1);
$reset = array_combine($keys, $arr);
print_r($reset);
Array
(
[0] => 10
[1] => 20
)
Подходит, когда нужно получить массив с определёнными числовыми ключами (например, начинать не с нуля, а с единицы - заменив range(0, ...) на range(1, ...)).
Проблема: при несовпадении количества ключей и значений (например, если count($arr) вычислено неправильно) возникнет ошибка E_WARNING. Требуется осторожность.
Как сбросить ключи с помощью json_decode и json_encode?
Неэффективный, но возможно, занимательный способ: преобразовать массив в JSON и обратно. При декодировании получается объект или массив, но если указать второй параметр true, то ключи будут переиндексированы.
$arr = ['a' => 1, 'b' => 2];
$reset = json_decode(json_encode($arr), true);
print_r($reset);
Array
(
[0] => 1
[1] => 2
)
Не рекомендуется для серьёзного использования из-за потери производительности и потенциальных проблем с типами данных (например, большие целые числа или специальные символы).
Проблема: при JSON-кодировании некоторые типы данных могут быть изменены (например, ресурсы, объекты). Также этот подход медленнее, чем array_values.
Расширенные примеры сброса ключей массива
Пример 1: array_values после фильтрации
Часто array_filter оставляет ключи нетронутыми. Сброс ключей делает массив снова последовательным.
$users = [
0 => ['name' => 'Alice', 'active' => true],
1 => ['name' => 'Bob', 'active' => false],
4 => ['name' => 'Charlie', 'active' => true]
];
$activeUsers = array_filter($users, function($user) {
return $user['active'];
});
print_r($activeUsers);
echo 'После сброса ключей:' . PHP_EOL;
$activeUsers = array_values($activeUsers);
print_r($activeUsers);
Array
(
[0] => Array ( [name] => Alice [active] => 1 )
[4] => Array ( [name] => Charlie [active] => 1 )
)
После сброса ключей:
Array
(
[0] => Array ( [name] => Alice [active] => 1 )
[1] => Array ( [name] => Charlie [active] => 1 )
)
Пример 2: Рекурсивный сброс ключей многомерного массива
Для вложенных массивов требуется рекурсия. Функция сбрасывает ключи на всех уровнях.
function resetArrayKeysRecursive(array $array): array {
$reset = [];
foreach ($array as $key => $value) {
if (is_array($value)) {
$reset[] = resetArrayKeysRecursive($value);
} else {
$reset[] = $value;
}
}
return $reset;
}
$multi = [
'group1' => ['a' => 1, 'b' => 2],
'group2' => ['c' => 3, 'd' => 4]
];
print_r(resetArrayKeysRecursive($multi));
Array
(
[0] => Array
(
[0] => 1
[1] => 2
)
[1] => Array
(
[0] => 3
[1] => 4
)
)
Пример 3: Сброс ключей с сохранением определённых ключей (пользовательская нумерация)
Используя array_combine можно задать произвольные числовые ключи, например, начиная с 100.
$arr = ['a' => 100, 'b' => 200, 'c' => 300];
$newKeys = range(100, 100 + count($arr) - 1);
$reset = array_combine($newKeys, $arr);
print_r($reset);
Array
(
[100] => 100
[101] => 200
[102] => 300
)
Пример 4: Сброс ключей с одновременным изменением значений
Через array_map можно применить произвольную функцию к каждому элементу.
$names = ['alice', 'bob', 'charlie'];
$upper = array_map('strtoupper', $names);
print_r($upper);
Array
(
[0] => ALICE
[1] => BOB
[2] => CHARLIE
)
Пример 5: Сброс ключей через array_values для ассоциативного массива с пропущенными ключами
$arr = [
5 => 'apple',
10 => 'banana',
'fruit' => 'cherry'
];
$reset = array_values($arr);
print_r($reset);
// Вывод: [0 => 'apple', 1 => 'banana', 2 => 'cherry']
Array
(
[0] => apple
[1] => banana
[2] => cherry
)
Пример 6: Использование array_merge для сброса ключей
Хотя это неявное применение, array_merge с одним массивом переиндексирует числовые ключи.
$arr = [2 => 'x', 5 => 'y'];
$reset = array_merge($arr);
print_r($reset);
// Вывод: [0 => 'x', 1 => 'y']
Array
(
[0] => x
[1] => y
)
Внимание: array_merge перезаписывает строковые ключи, если они совпадают. Для ассоциативных массивов со строковыми ключами это не сработает (ключи останутся).