Подтвердить что ты не робот

Удалите все элементы массива с помощью нечисловых клавиш

У меня есть массив, который выглядит примерно так:

Array
(
    [0] => apple
    ["b"] => banana
    [3] => cow
    ["wrench"] => duck
)

Я хочу взять этот массив и использовать array_filter или что-то подобное, чтобы удалить элементы с нечисловыми ключами и получить следующий массив:

Array
(
    [0] => apple
    [3] => cow
)

Я думал об этом, и я не мог придумать, как это сделать, потому что array_filter не предоставляет мою функцию с ключом, и array_walk не может изменять структуру массива (об этом говорится в руководстве по PHP).

4b9b3361

Ответ 1

Использование цикла foreach было бы подходящим в этом случае:

foreach ($arr as $key => $value) {
    if (!is_int($key)) {
        unset($arr[$key]);
    }
}

Ответ 2

Это можно сделать без написания цикла в одном (длинном) строке:

$a = array_intersect_key($a, array_flip(array_filter(array_keys($a), 'is_numeric')));

Что он делает:

  • Так как array_filter работает со значениями, array_keys сначала создает новый массив с ключами как значения (игнорируя исходные значения).
  • Затем они фильтруются функцией is_numeric.
  • Затем результат отбрасывается, так что клавиши снова становятся ключами.
  • Наконец, array_intersect_key принимает только элементы из исходного массива, имеющие ключ в результате вышеперечисленного (числовые клавиши).

Не спрашивайте меня о производительности, хотя.

Ответ 3

Начиная с PHP 5.6, теперь можно использовать array_filter в компактной форме:

array_filter($array, function ($k) { return is_numeric($k); }, ARRAY_FILTER_USE_KEY);

Demo.

Этот подход примерно на 20% медленнее, чем цикл for на моем компьютере (1,61 с против 1,31 с для 1M итераций).


Начиная с PHP 7.4, можно также использовать короткие замыкания ::

array_filter($array, fn($k) => is_numeric($k), ARRAY_FILTER_USE_KEY);

Ответ 4

Здесь цикл:

foreach($arr as $key => $value) {
    if($key !== 0 and !intval($key)) {
         unset($arr[$key]);
    }
}