PHP array_filter() 過濾陣列
array_filter() 函數用來過濾陣列中的元素,保留符合條件的元素。
基本用法
<?php
$numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
$evens = array_filter($numbers, fn($n) => $n % 2 === 0);
print_r($evens);
// [1 => 2, 3 => 4, 5 => 6, 7 => 8, 9 => 10]
// 注意:鍵會被保留
?>
語法
array_filter(array $array, ?callable $callback = null, int $mode = 0): array
$array:要過濾的陣列$callback:過濾函數,回傳true保留元素$mode:決定傳入回呼的參數- 回傳值:過濾後的陣列(保留原鍵)
不帶回呼函數
不帶回呼函數時,會過濾掉所有「假值」:
<?php
$arr = [0, 1, '', 'hello', null, false, [], [1, 2]];
$filtered = array_filter($arr);
print_r($filtered);
// [1 => 1, 3 => 'hello', 7 => [1, 2]]
?>
被過濾掉的假值:
false0和0.0''(空字串)'0'(字串零)[](空陣列)null
過濾模式
ARRAY_FILTER_USE_KEY
只傳入鍵到回呼函數:
<?php
$arr = ['a' => 1, 'b' => 2, 'c' => 3, 'd' => 4];
$filtered = array_filter($arr, fn($key) => $key !== 'b', ARRAY_FILTER_USE_KEY);
print_r($filtered);
// ['a' => 1, 'c' => 3, 'd' => 4]
?>
ARRAY_FILTER_USE_BOTH
同時傳入值和鍵到回呼函數:
<?php
$arr = ['a' => 1, 'b' => 2, 'c' => 3, 'd' => 4];
$filtered = array_filter(
$arr,
fn($value, $key) => $key !== 'b' && $value > 1,
ARRAY_FILTER_USE_BOTH
);
print_r($filtered);
// ['c' => 3, 'd' => 4]
?>
重新索引
array_filter() 會保留原本的鍵,如果需要重新索引:
<?php
$numbers = [1, 2, 3, 4, 5];
$filtered = array_filter($numbers, fn($n) => $n > 2);
print_r($filtered);
// [2 => 3, 3 => 4, 4 => 5]
// 重新索引
$reindexed = array_values($filtered);
print_r($reindexed);
// [0 => 3, 1 => 4, 2 => 5]
?>
常見應用
過濾空值
<?php
$data = ['Alice', '', 'Bob', null, 'Charlie', ' '];
// 過濾假值
$filtered = array_filter($data);
// 過濾空白字串
$filtered = array_filter($data, fn($v) => trim($v ?? '') !== '');
print_r($filtered); // ['Alice', 'Bob', 'Charlie']
?>
過濾數字範圍
<?php
$numbers = [5, 12, 8, 130, 44, 3, 67];
// 大於 10
$large = array_filter($numbers, fn($n) => $n > 10);
// 範圍內
$range = array_filter($numbers, fn($n) => $n >= 10 && $n <= 100);
print_r($range); // [12, 44, 67]
?>
過濾物件/關聯陣列
<?php
$users = [
['name' => 'Alice', 'age' => 25, 'active' => true],
['name' => 'Bob', 'age' => 30, 'active' => false],
['name' => 'Charlie', 'age' => 35, 'active' => true],
];
// 過濾活躍使用者
$active = array_filter($users, fn($u) => $u['active']);
// 過濾年齡大於 28
$older = array_filter($users, fn($u) => $u['age'] > 28);
print_r($active);
?>
過濾檔案類型
<?php
$files = ['doc.pdf', 'image.jpg', 'data.json', 'photo.png', 'text.txt'];
// 只保留圖片
$images = array_filter($files, function($file) {
$ext = pathinfo($file, PATHINFO_EXTENSION);
return in_array($ext, ['jpg', 'png', 'gif', 'webp']);
});
print_r($images); // ['image.jpg', 'photo.png']
?>
搜尋過濾
<?php
$products = [
['name' => 'iPhone', 'category' => 'Electronics', 'price' => 999],
['name' => 'T-Shirt', 'category' => 'Clothing', 'price' => 29],
['name' => 'MacBook', 'category' => 'Electronics', 'price' => 1999],
['name' => 'Jeans', 'category' => 'Clothing', 'price' => 59],
];
// 多條件過濾
$filtered = array_filter($products, function($p) {
return $p['category'] === 'Electronics' && $p['price'] < 1500;
});
print_r($filtered);
// [['name' => 'iPhone', ...]]
?>
去除重複(自訂邏輯)
<?php
$users = [
['id' => 1, 'name' => 'Alice'],
['id' => 2, 'name' => 'Bob'],
['id' => 1, 'name' => 'Alice Duplicate'], // 重複 ID
];
$seen = [];
$unique = array_filter($users, function($user) use (&$seen) {
if (in_array($user['id'], $seen)) {
return false;
}
$seen[] = $user['id'];
return true;
});
print_r($unique);
?>
array_filter vs foreach
<?php
$numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// 使用 array_filter
$evens = array_filter($numbers, fn($n) => $n % 2 === 0);
// 使用 foreach
$evens = [];
foreach ($numbers as $key => $n) {
if ($n % 2 === 0) {
$evens[$key] = $n;
}
}
// 兩者結果相同
?>
組合使用
<?php
$users = [
['name' => 'alice', 'age' => 25],
['name' => 'bob', 'age' => 17],
['name' => 'charlie', 'age' => 30],
];
// 過濾成年人並格式化名稱
$adults = array_values(
array_map(
fn($u) => [...$u, 'name' => ucfirst($u['name'])],
array_filter($users, fn($u) => $u['age'] >= 18)
)
);
print_r($adults);
// [
// ['name' => 'Alice', 'age' => 25],
// ['name' => 'Charlie', 'age' => 30]
// ]
?>
效能考量
<?php
// 大量資料時,考慮使用生成器
function filterLarge(array $arr, callable $callback): Generator {
foreach ($arr as $key => $value) {
if ($callback($value, $key)) {
yield $key => $value;
}
}
}
$large = range(1, 1000000);
$filtered = filterLarge($large, fn($n) => $n % 2 === 0);
// 逐一處理,不會一次載入所有結果
foreach ($filtered as $value) {
// ...
}
?>
注意事項
<?php
// array_filter 回傳新陣列,不修改原陣列
$arr = [1, 2, 3, 4, 5];
$filtered = array_filter($arr, fn($n) => $n > 2);
print_r($arr); // [1, 2, 3, 4, 5](不變)
print_r($filtered); // [2 => 3, 3 => 4, 4 => 5]
// 回呼函數應該回傳布林值
$arr = [1, 2, 3];
$result = array_filter($arr, fn($n) => $n); // 非布林值會被轉換
?>