18

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

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

我想获取该数组并使用 array_filter 或类似的东西来删除具有非数字键的元素并接收以下数组:

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

我正在考虑这个问题,但我想不出办法来做到这一点,因为 array_filter 没有为我的函数提供密钥,并且 array_walk 无法修改数组结构(在 PHP 手册中谈到)。

4

4 回答 4

35

在这种情况下使用foreach循环是合适的:

foreach ($arr as $key => $value) {
    if (!is_int($key)) {
        unset($arr[$key]);
    }
}
于 2012-06-14T23:07:00.683 回答
24

无需在一行(长)中编写循环即可完成:

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

它能做什么:

  • 由于array_filter使用值,array_keys首先创建一个以键为值的新数组(忽略原始值)。
  • 然后这些由is_numeric函数过滤。
  • 然后将结果翻转回来,因此键再次成为键。
  • 最后,array_intersect_key仅从原始数组中获取在上述结果中具有键的项目(数字键)。

不过不要问我关于性能的问题。

于 2013-08-28T14:01:26.817 回答
21

从 PHP 5.6 开始,现在可以以array_filter紧凑的形式使用:

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

演示。

这种方法比我的盒子上的循环慢约 20% for(1.61s 与 1.31s 的 1M 迭代)。


从 PHP 7.4 开始,也可以使用短闭包::

array_filter($array, fn($k) => is_numeric($k), ARRAY_FILTER_USE_KEY);
于 2016-07-19T14:44:06.470 回答
6

这是一个循环:

foreach($arr as $key => $value) {
    if($key !== 0 and !intval($key)) {
         unset($arr[$key]);
    }
}
于 2012-06-14T23:07:29.157 回答