过滤数组

为了从数组中过滤掉值并获得包含满足过滤条件的所有值的新数组,可以使用 array_filter 函数。

过滤非空值

最简单的过滤方法是删除所有值:

$my_array = [1,0,2,null,3,'',4,[],5,6,7,8];
$non_empties = array_filter($my_array); // $non_empties will contain [1,2,3,4,5,6,7,8]; 

通过回调过滤

这次我们定义自己的过滤规则。假设我们只想得到偶数:

$my_array = [1,2,3,4,5,6,7,8];

$even_numbers = array_filter($my_array, function($number) {
    return $number % 2 === 0;   
});

array_filter 函数接收要过滤的数组作为其第一个参数,以及将过滤谓词定义为第二个参数的回调。

Version >= 5.6

按索引过滤

可以向 array_filter 函数提供第三个参数,该参数允许调整传递给回调的值。此参数可以设置为 ARRAY_FILTER_USE_KEYARRAY_FILTER_USE_BOTH,这将导致回调接收键而不是数组中每个元素的值,或者值和键作为其参数。例如,如果要处理索引而不是值:

$numbers = [16,3,5,8,1,4,6];

$even_indexed_numbers = array_filter($numbers, function($index) {
    return $index % 2 === 0;
}, ARRAY_FILTER_USE_KEY);

过滤后的数组中的索引

请注意,array_filter 保留原始数组键。一个常见的错误是尝试在过滤后的数组上使用 for 循环:

<?php

$my_array = [1,0,2,null,3,'',4,[],5,6,7,8];
$filtered = array_filter($my_array); 

error_reporting(E_ALL); // show all errors and notices

// innocently looking "for" loop
for ($i = 0; $i < count($filtered); $i++) {
   print $filtered[$i];
}

/*
Output:
1
Notice: Undefined offset: 1
2
Notice: Undefined offset: 3
3
Notice: Undefined offset: 5
4
Notice: Undefined offset: 7
*/

这是因为位置 1(有 0),3(null),5(空字符串'')和 7(空数组 [])上的值以及它们对应的索引键被删除。

如果需要在索引数组上循环遍历过滤器的结果,则应首先在 array_filter 的结果上调用 array_values,以便创建具有正确索引的新数组:

$my_array = [1,0,2,null,3,'',4,[],5,6,7,8];
$filtered = array_filter($my_array); 
$iterable = array_values($filtered);

error_reporting(E_ALL); // show all errors and notices

for ($i = 0; $i < count($iterable); $i++) {
   print $iterable[$i];
}

// No warnings!