array_filter

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

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

描述

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

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

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

参数

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)
}

备注

注意

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

参见

添加注释

用户贡献的注释 11 条注释

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

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

?>
Niko E
1 年前
请注意,经过过滤的数组不再编码为 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"]
Merlindog
1 年前
上面已经清楚地说明了这一点,但请确保您永远不会忘记,当设置 ARRAY_FILTER_USE_BOTH 时,回调参数的顺序是值、键 - 而不是键、值。这将为您节省一些时间。
nicolaj dot knudsen at gmail dot com
7 年前
如果您像我一样,由于使用了按位运算符 (&) 而难以理解示例 #1,以下是一个解释。

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

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

如果给定一个整数,则此函数返回整数 1(如果 $var 为奇数)和整数 0(如果 $var 为偶数)。
单个按位与运算符 & 是按位与运算符。它的工作原理是获取两个参数的二进制表示,并使用 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 上使用 for 循环,除非先通过 array_values() 处理它。
ASchmidt at Anamera dot net
2 年前
根据您的“空”数组值的预期含义,例如 null 和空字符串,与整数 0 或布尔值 false 相比,请注意不同过滤器产生的结果。

<?php
declare(strict_types=1);

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

// 删除 null、null 字符串 - 但也删除 FALSE!
$filtered1 = array_filter( $array, 'strlen' );

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

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

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

结果为

array (size=3)
'intzero' => int 0
'stringzero' => string '0' (length=1)
'stringfalse' => string 'false' (length=5)

array (size=5)
'nullstring' => string '' (length=0)
'intzero' => int 0
'stringzero' => string '0' (length=1)
'false' => boolean false
'stringfalse' => string 'false' (length=5)

array (size=4)
'intzero' => int 0
'stringzero' => string '0' (length=1)
'false' => boolean false
'stringfalse' => string 'false' (length=5)
hello at damian-gonzalez dot com
1 天前
上面的文档或任何注释中都没有提到,但如果您的匿名函数需要来自外部的变量,则必须使用 "use" 关键字,否则它将无法工作。

示例 1

<?php

$people
= [
[
'id' => 23,
'name' => 'John',
'lastname' => 'Williams',
],
[
'id' => 56,
'name' => 'Hans',
'lastname' => 'Zimmer',
],
];

function
filter_by_name ($name) {
global
$people;
$filtered = array_filter($people, function($n) use($name) {
return
$n['name'] == $name;
});
return
$filtered;
}

print_r (filter_by_name ('John'));
?>

示例 2,使用多个变量

<?php

$people
= [
[
'id' => 23,
'name' => 'John',
'lastname' => 'Williams',
],
[
'id' => 56,
'name' => 'Hans',
'lastname' => 'Zimmer',
],
];

function
filter_array_by_column ($array, $column, $value) {

$filtered = array_filter($array, function($row) use($column, $value) {
return
$row[$column] == $value;
});
return
$filtered;
}

print_r (filter_array_by_column ($people, 'name', 'John'));
?>
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 is gone!

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