在array_filter()之后,如何重置键以数字顺序从0开始


108

我只是使用array_filter从数组中删除仅具有值''的条目,现在我想根据从0开始的占位符对其应用某些转换,但不幸的是,它仍保留原始索引。我看了一会儿,什么也没看到,也许我只是错过了明显的地方,但是我的问题是...

我如何轻松地将数组的索引重置为从0开始并在NEW数组中顺序排列,而不是保留旧索引?



除非您绝对确定数组中没有空/零值/假值,否则我必须敦促您不要使用array_filter()-您可能会清除超出预期的范围。这是一个演示的解释:stackoverflow.com/a/43657056/2943403
mickmackusa

Answers:



37

如果您使用数组过滤器,请按照以下步骤操作

$NewArray = array_values(array_filter($OldArray));

3
哦,我迷失在试图弄清楚为什么json_encode一个数组的结果与json_encode一个array_filtered数组的结果不同的时候……谢谢您……
Jerther 2015年

13

我担心有多少程序员无辜地将array_values(array_filter())方法复制/粘贴到了他们的代码中 -我不知道有多少程序员由于array_filter的贪婪而无意间遇到了问题。更糟糕的是,有多少人从未发现该函数从数组中清除了太多的值...

对于NULL从数组中剥离元素并重新索引键的两部分过程,我将提出一个更好的选择。

但是,首先,我要特别强调它的贪婪性array_filter()以及它如何能够无声地破坏您的项目,这一点非常重要。这是一个包含混合值的数组,这将暴露出问题:

$array=['foo',NULL,'bar',0,false,null,'0',''];

空值将被删除,而不管大小写如何。

但是看看当我们使用array_values()array_filter()时,数组中还剩下什么:

array_values(array_filter($array));

输出数组($ array):

array (
  0 => 'foo',
  1 => 'bar'
)
// All empty, zero-ish, falsey values were removed too!!!

现在看一下使用array_walk()is_null()生成新的过滤数组的方法所得到的结果:

array_walk($array,function($v)use(&$filtered){if(!is_null($v)){$filtered[]=$v;}});

可以将其写在多行上,以便于阅读/解释:

array_walk(                      // iterate each element of an input array
    $array,                      // this is the input array
    function($v)use(&$filtered){ // $v is each value, $filter (output) is declared/modifiable
        if(!is_null($v)){        // this literally checks for null values
            $filtered[]=$v;      // value is pushed into output with new indexes
        }
    }
);

输出数组($ filter):

array (
  0 => 'foo',
  1 => 'bar',
  2 => 0,
  3 => false,
  4 => '0',
  5 => '',
)

使用我的方法,您可以获得重新索引的键,所有非空值和所有空值。干净,便携式,可靠的一线包装,可满足您所有阵列空值过滤的需求。这是一个示范



同样,如果要删除空,假和空元素(保留零),这四个方法将起作用:

var_export(array_values(array_diff($array,[''])));

要么

var_export(array_values(array_diff($array,[null])));

要么

var_export(array_values(array_diff($array,[false])));

要么

var_export(array_values(array_filter($array,'strlen')));

输出:

array (
  0 => 'foo',
  1 => 'bar',
  2 => 0,
  3 => '0',
)

最后,对于任何喜欢语言构造语法的人,您也可以将限定值推入新数组以发出新索引。

$array=['foo', NULL, 'bar', 0, false, null, '0', ''];

$result = [];
foreach ($array as $value) {
    if (strlen($value)) {
        $result[] = $value;
    }
}

var_export($result);

2
如果您写作,事情不会按照预期的方式表现array_values(array_filter($arr, function($el) {return $el !== '';}))吗?这似乎是OP所要求的自然方法。
Casey

1
是。我的观点是,开发人员应避免使用默认行为,array_filter()除非他们对数据的深入了解允许贪婪过滤而没有副作用。(进一步的警告:empty()以同样的方式表现,并且在贪婪中也包含一个空数组。)
mickmackusa

2
该答复回答了完全不同的问题,无论以任何形式,形式或形式都与原始问题无关。
AnrDaemon

1
array_filter()根据手册中的内容,其行为完全符合您的期望:php.net/manual/en/function.array-filter.php “如果未提供回调,则数组的所有条目均等于FALSE(请参阅转换为boolean )将被删除。” 在PHP程序员中,应该普遍知道0,null,false,''和'0'在被强制为布尔值时都评估为false。
madsen

1
事实是,大多数人都不知道会发生什么。你知道,我知道,但很多人不知道。我发布了此答案以帮助不认识的人。
mickmackusa

12

用途array_values()

<?php

$array = array('foo', 'bar', 'baz');
$array = array_filter($array, function ($var) {
    return $var !== 'bar';
});

print_r($array); // indexes 0 and 2
print_r(array_values($array)); // indexes 0 and 1
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.