删除数组中具有非数字键的所有元素


Remove all elements of an array with non-numeric keys

我有一个看起来像这样的数组:

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);

演示。

这种方法比我的盒子上的for循环慢大约 20%(1.61 秒,而 1M 迭代为 1.31 秒)。


从 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]);
    }
}