Ответ 1
Использование цикла foreach
было бы подходящим в этом случае:
foreach ($arr as $key => $value) {
if (!is_int($key)) {
unset($arr[$key]);
}
}
У меня есть массив, который выглядит примерно так:
Array
(
[0] => apple
["b"] => banana
[3] => cow
["wrench"] => duck
)
Я хочу взять этот массив и использовать array_filter или что-то подобное, чтобы удалить элементы с нечисловыми ключами и получить следующий массив:
Array
(
[0] => apple
[3] => cow
)
Я думал об этом, и я не мог придумать, как это сделать, потому что array_filter не предоставляет мою функцию с ключом, и array_walk не может изменять структуру массива (об этом говорится в руководстве по PHP).
Использование цикла foreach
было бы подходящим в этом случае:
foreach ($arr as $key => $value) {
if (!is_int($key)) {
unset($arr[$key]);
}
}
Это можно сделать без написания цикла в одном (длинном) строке:
$a = array_intersect_key($a, array_flip(array_filter(array_keys($a), 'is_numeric')));
Что он делает:
- Так как
array_filter
работает со значениями,array_keys
сначала создает новый массив с ключами как значения (игнорируя исходные значения).- Затем они фильтруются функцией
is_numeric
.- Затем результат отбрасывается, так что клавиши снова становятся ключами.
- Наконец,
array_intersect_key
принимает только элементы из исходного массива, имеющие ключ в результате вышеперечисленного (числовые клавиши).
Не спрашивайте меня о производительности, хотя.
Начиная с PHP 5.6, теперь можно использовать array_filter
в компактной форме:
array_filter($array, function ($k) { return is_numeric($k); }, ARRAY_FILTER_USE_KEY);
Этот подход примерно на 20% медленнее, чем цикл for
на моем компьютере (1,61 с против 1,31 с для 1M итераций).
Начиная с PHP 7.4, можно также использовать короткие замыкания ::
array_filter($array, fn($k) => is_numeric($k), ARRAY_FILTER_USE_KEY);
Здесь цикл:
foreach($arr as $key => $value) {
if($key !== 0 and !intval($key)) {
unset($arr[$key]);
}
}