PHP Conference Japan 2024

array_filter

(PHP 4 >= 4.0.6, PHP 5, PHP 7, PHP 8)

array_filter使用回调函数过滤数组元素

描述

array_filter(数组 $array, ?callable $callback = null, int $mode = 0): 数组

迭代array中的每个值,并将它们传递给callback函数。如果callback函数返回true,则array中的当前值将返回到结果数组

数组键被保留,如果array是索引数组,则可能导致间隙。可以使用array_values()函数重新索引结果数组

参数

array

要迭代的数组

callback

要使用的回调函数

如果没有提供callback,则将删除array的所有空条目。有关 PHP 在此情况下如何定义空的说明,请参见empty()

mode

确定发送给callback的参数的标志

默认为0,它将值作为唯一参数传递给callback

返回值

返回过滤后的数组。

变更日志

版本 描述
8.0.0 callback现在可以为空。
8.0.0 如果callback期望通过引用传递参数,则此函数现在将发出E_WARNING

示例

示例 #1 array_filter() 示例

<?php
function odd($var)
{
// 返回输入整数是否为奇数
return $var & 1;
}

function
even($var)
{
// 返回输入整数是否为偶数
return !($var & 1);
}

$array1 = ['a' => 1, 'b' => 2, 'c' => 3, 'd' => 4, 'e' => 5];
$array2 = [6, 7, 8, 9, 10, 11, 12];

echo
"奇数:\n";
print_r(array_filter($array1, "odd"));
echo
"偶数:\n";
print_r(array_filter($array2, "even"));
?>

以上示例将输出

Odd :
Array
(
    [a] => 1
    [c] => 3
    [e] => 5
)
Even:
Array
(
    [0] => 6
    [2] => 8
    [4] => 10
    [6] => 12
)

示例 #2 array_filter() 不带callback

<?php

$entry
= [
0 => 'foo',
1 => false,
2 => -1,
3 => null,
4 => '',
5 => '0',
6 => 0,
];

print_r(array_filter($entry));
?>

以上示例将输出

Array
(
    [0] => foo
    [2] => -1
)

示例 #3 array_filter()mode

<?php

$arr
= ['a' => 1, 'b' => 2, 'c' => 3, 'd' => 4];

var_dump(array_filter($arr, function($k) {
return
$k == 'b';
},
ARRAY_FILTER_USE_KEY));

var_dump(array_filter($arr, function($v, $k) {
return
$k == 'b' || $v == 4;
},
ARRAY_FILTER_USE_BOTH));
?>

以上示例将输出

array(1) {
  ["b"]=>
  int(2)
}
array(2) {
  ["b"]=>
  int(2)
  ["d"]=>
  int(4)
}

注释

警告

如果数组在回调函数中被修改(例如,添加或取消设置元素),则此函数的行为未定义。

参见

添加注释

用户贡献的注释 10 条注释

匿名
11 年前
如果您想要一种快速去除 NULL、FALSE 和空字符串 (""),但保留 0(零)值的方法,您可以使用标准的 php 函数 strlen 作为回调函数
例如
<?php

// 删除所有 NULL、FALSE 和空字符串,但保留 0(零)值
$result = array_filter( $array, 'strlen' );

?>
Merlindog
1 年前
上面已经清楚地说明了这一点,但是请务必记住,当设置 ARRAY_FILTER_USE_BOTH 时,回调参数的顺序是值、键 - 而不是键、值。这将节省您一些时间。
Niko E
2 年前
请注意,过滤后的数组不再编码为 json 数组,因为索引不再连续。

$a = ['a', 'b', 'c'];
var_dump(json_encode($a)); // ["a","b","c"]
$a = array_filter($a, function ($x) { return $x == 'b'; });
var_dump(json_encode($a)); // {"1": "b"}

您可以使用 array_values 获取连续数组

var_dump(json_encode(array_values($a))); // ["b"]
nicolaj dot knudsen at gmail dot com
7 年前
如果像我一样,由于使用了按位运算符 (&) 而难以理解示例 #1,这里有一个解释。

问题所在的部分是这个回调函数

<?php
function odd($var)
{
// 返回输入整数是否为奇数
return($var & 1);
}
?>

如果给定一个整数,则此函数如果 $var 为奇数则返回整数 1,如果 $var 为偶数则返回整数 0。
单&符号是按位 AND 运算符。它的工作方式是获取两个参数的二进制表示,并使用 AND 对它们逐位进行比较。如果 $var = 45,则由于 45 的二进制表示为 101101,因此操作如下所示

45 的二进制表示:101101
1 的二进制表示:000001
------
结果:000001

只有当 $var 的二进制表示中的最后一位变为零(意味着该值为偶数)时,结果才会变为 000000,这是零的表示。
TechNyquist
2 年前
请记住,从 PHP 7.4 及更高版本开始,您可以使用箭头函数作为参数。
例如,如果您想保留大于 10 的值

<?php
$arr
= array_filter($numbers, fn($n) => $n > 10);
?>

此外,结合键标志来剪切某些键

<?php
$arr
= array_filter($entries, fn($key) => !in_array($key, ['key1', 'key5']), ARRAY_FILTER_USE_KEY);
?>

等等。
Hayley Watson
1 年前
array_filter 保留键的事实使得将数组划分为[通过测试的元素,未通过测试的元素]非常容易。实质上

<?php
function partition($array, $test)
{
$pass = array_filter($array, $test);
$fail = array_diff_key($array, $pass);
return [
false => $fail, true => $pass];
}
?>

array_diff_key 调用是关键;如所示对返回的数组进行索引允许诸如“$failures = $partition[false];”之类的行执行正确的事情(布尔值当然会转换为整数,但它是一致且自文档化的)。
marc dot vanwoerkom at fernuni-hagen dot de
20 年前
PHP 的一些数组函数在所谓的函数式编程语言中扮演着重要的角色,在那里它们以略微不同的名称出现

<?php
array_filter
() -> filter(),
array_map() -> map(),
array_reduce() -> foldl() ("fold left")
?>

函数式编程是一种范式,它围绕函数的无副作用评估展开。程序执行是函数调用,而函数调用又可能由许多其他函数定义。一个想法是使用函数从其他函数创建专用函数。

上面提到的数组函数允许您在数组上组合新函数。

例如,array_sum = array_map("sum", $arr)。

这导致了一种看起来非常像代数的编程风格,例如 Bird/Meertens 形式主义。

例如,数学家可能会声明

map(f o g) = map(f) o map(g)

所谓的“循环融合”定律。

许多数组函数可以通过使用 foldr() 函数(其工作方式类似于 foldl,但从右边吃掉数组元素)来创建。

我在这里无法详细说明,我只是想提供一个关于这些内容的出现位置以及背后的理论的提示。
marc dot gray at gmail dot com
10 年前
我最喜欢的此函数用法是将字符串转换为数组,修剪每一行并删除空行

<?php
$array
= array_filter(array_map('trim', explode("\n", $string)), 'strlen');
?>

尽管它清楚地说明了数组键被保留,但重要的是要注意这包括按数字索引的数组。在不首先通过 array_values() 处理 $array 的情况下,您无法在其上使用 for 循环。
ASchmidt at Anamera dot net
3 年前
根据您“空”数组值的预期含义,例如 null 和空字符串与整数 0 或布尔值 false,请注意不同过滤器的结果。

<?php
声明(strict_types=1);

$array = array( 'null' => null, 'nullstring' => '', 'intzero' => 0, 'stringzero' => '0', 'false' => false, 'stringfalse' => 'false', );

// 删除null和空字符串——但也删除了FALSE!
$filtered1 = array_filter( $array, 'strlen' );

// 只删除null。
$filtered2 = array_filter( $array, function( $v ) { return !is_null( $v ); } );

// 删除null和空字符串。保留FALSE和0。
$filtered3 = array_filter( $array, function( $v ) { return !( is_null( $v) or '' === $v ); } );

var_dump( $array, $filtered1, $filtered2, $filtered3 );
?>

结果:

数组 (大小:3)
'intzero' => int 0
'stringzero' => string '0' (长度:1)
'stringfalse' => string 'false' (长度:5)

数组 (大小:5)
'nullstring' => string '' (长度:0)
'intzero' => int 0
'stringzero' => string '0' (长度:1)
'false' => boolean false
'stringfalse' => string 'false' (长度:5)

数组 (大小:4)
'intzero' => int 0
'stringzero' => string '0' (长度:1)
'false' => boolean false
'stringfalse' => string 'false' (长度:5)
justinphiggs at gmail dot com
2 年前
检查数组中所有元素是否非空/非null/非假值。
------------------------------
假设你有一个一维数组……

<?php
$spicy_numbers
= [69, 420, ɸ];
?>

并且你想轻松地检查该数组中的所有元素是否都不是null/empty/任何假值,而不是遍历每个元素,你可以将数组传递给<?php array_filter() ?>,不带回调函数,然后检查返回的数组是否与原始数组大小相同,因为<?php array_filter() ?>在不提供回调函数时会去除所有非真值,包括0。

示例
<?php
$spicy_numbers
= [69, 420, '']; // Phi不见了!

if ( count( array_filter( $spicy_numbers ) ) !== count( $spicy_numbers ) ) {
// 其中一个元素为空/null/假值。
} else {
// 所有元素都存在且为真值。
}
?>

作为一个简洁的小函数,你可以这样做
<?php
/**
* 检查给定数组的所有元素是否具有非假值。
* 用例:如果数组中的所有项目都已设置并具有值(当然是真值),则执行X;否则,执行Y。
*
* @param array $arr
* @return bool
*/
function is_array_full( $arr ) {
$array_count = count( $arr );
$filtered_count = count( array_filter( $arr ) );

return (
$array_count === $filtered_count ) ? true : false;
}
?>
To Top