2024 日本 PHP 研討會

array_filter

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

array_filter使用回呼函式過濾陣列元素

說明

array_filter(陣列 $array, ?可呼叫 $callback = null, 整數 $mode = 0): 陣列

迭代 array 中的每個值,並將它們傳遞給 callback 函式。如果 callback 函式回傳 true,則 array 中的目前值將會被回傳到結果 陣列 中。

陣列鍵值會被保留,如果 array 是索引陣列,則結果中可能會有間隔。可以使用 array_values() 函式重新索引結果 陣列

參數

array

要迭代的陣列

callback

要使用的回呼函式

如果沒有提供 callback,則 array 中所有空項目將會被移除。關於 PHP 如何定義空項目,請參考 empty()

mode

決定傳遞給 callback 的參數的旗標

預設值為 0,這會將值作為唯一參數傳遞給 callback

回傳值

回傳過濾後的陣列。

更新日誌

版本 說明
8.0.0 callback 現在可以為 null。
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() ("由左摺疊")
?>

函數式程式設計是一種以無副作用的函式求值為中心的範式。程式執行是函式的呼叫,而函式又可能由許多其他函式定義。一個想法是使用函式從其他函式創建特殊用途的函式。

上面提到的陣列函式允許您在陣列上組合新的函式。

例如,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
3 年前
根據您「空」陣列值的預期含義,例如 null 和空字串,與整數 0 或布林值 false,請注意不同過濾器的結果。

<?php
declare(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' => 字串 '0' (長度=1)
'stringfalse' => 字串 'false' (長度=5)

陣列 (大小=5)
'nullstring' => 字串 '' (長度=0)
'intzero' => int 0
'stringzero' => 字串 '0' (長度=1)
'false' => 布林值 false
'stringfalse' => 字串 'false' (長度=5)

陣列 (大小=4)
'intzero' => int 0
'stringzero' => 字串 '0' (長度=1)
'false' => 布林值 false
'stringfalse' => 字串 'false' (長度=5)
justinphiggs at gmail dot com
2 年前
檢查陣列中所有元素是否不為空/null/假值。
------------------------------
假設你有一個一維陣列...

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

而且你想要輕鬆地檢查該陣列中的所有元素是否不為 null/空/任何假值,而不是對每個元素執行迴圈,你可以將陣列傳遞給 <?php array_filter() ?>,不帶回呼函式,然後檢查返回的陣列是否與原始陣列大小相同,因為當沒有提供回呼函式時,<?php array_filter() ?> 會去除所有非真值,包括 0。

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

if ( count( array_filter( $spicy_numbers ) ) !== count( $spicy_numbers ) ) {
// 其中一個元素是空的/null/false。
} else {
// 所有元素都存在且為 true。
}
?>

您可以將它寫成一個簡潔的小函式:
<?php
/**
* 檢查給定陣列的所有元素是否都具有非 false 的值。
* 使用案例:如果陣列中的所有項目都已設定且具有值(當然是 true),則執行 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