我刚刚使用了array_filter从数组中删除了只有''值的条目,现在我想根据从0开始的占位符对其应用某些转换,但不幸的是,它仍然保留原始索引。我找了一会儿也没有看到任何东西,也许我只是错过了显而易见的事情,但我的问题是...
如何轻松地重置数组的索引,使其从0开始并按顺序排列在新数组中,而不是保留旧索引?
array_values
,它将从零重新索引。如果您正在使用数组过滤,请按照以下方式进行操作
$NewArray = array_values(array_filter($OldArray));
使用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
我担心有多少程序员无意中复制粘贴了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 => '', )
使用我的方法,您可以获得重新索引的键、所有非null值和没有null值。这是一个干净、易于移植和可靠的单行代码,适用于所有的数组空值过滤需求。这里有一个演示。
同样地,如果您想要删除空、false和null元素(保留零),这四种方法都可以工作:
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);
array_values(array_filter($arr, function($el) {return $el !== '';}))
,事情不就会如预期一样吗?这似乎是实现OP所询问的自然方式。 - Caseyarray_filter()
的默认行为,除非他们对数据有深入了解,可以进行贪心过滤而不会产生副作用。(进一步提醒:empty()
也以相同方式表现,并且在其贪心中包括一个空数组。) - mickmackusaarray_filter()
,这很相关,因为谷歌搜索结果可能会将搜索“reindex after array_filter”的研究人员引导到这里。我的答案确实提供了几种实现所需结果的方法,这证明了这个答案是合适/相关的。如果您仍然不满意,我现在可以添加一种语言结构的替代方案。 - mickmackusaarray_filter()
函数的行为与手册上所说的一样:http://php.net/manual/en/function.array-filter.php
“如果没有提供回调函数,则将删除等于FALSE(参见转换为布尔值)的数组中的所有条目。” PHP程序员应该知道,0、null、false、''和'0'在强制转换为布尔值时都会被视为false。 - madsen
array_filter()
- 您可能会清除更多内容。这里有一些解释和演示:https://dev59.com/7nE85IYBdhLWcg3wr1ux#43657056 - mickmackusa