首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 陣列過濾利器:array_filter 移除空值、array_unique 去重、二維陣列去重

     編輯:PHP 相關知識

處理陣列時,array_filter 與 array_unique 是最高頻工具。本文詳細說明兩者用法、自定義回呼、效能對比,並提供「二維陣列去重」通用函式(原生 array_unique 僅支援一維)。

array_filter:過濾空值或自定義邏輯

基本用法(移除所有「空值」)

$arr = [0, 1, false, 2, '', 3, null, 'hello', []];
$filtered = array_filter($arr); // 無回呼時,移除等同 false 的值
// 結果:[1 => 1, 3 => 2, 5 => 3, 7 => 'hello']
// 注意:鍵名保留原索引,若需重新索引用 array_values()

自定義回呼:保留奇數

$arr = [1,2,3,4,5,6,7,8,9,10];
$odd = array_filter($arr, function($v) { return $v & 1; });
// [0=>1, 2=>3, 4=>5, 6=>7, 8=>9]

進階:ARRAY_FILTER_USE_KEY / BOTH

$arr = ['a'=>1, 'b'=>2, 'c'=>3, 'd'=>4];
// 依鍵名過濾
$byKey = array_filter($arr, function($k) { return $k !== 'b'; }, ARRAY_FILTER_USE_KEY);
// 同時使用鍵值
$byBoth = array_filter($arr, function($v, $k) { return $v > 2 && $k !== 'd'; }, ARRAY_FILTER_USE_BOTH);

array_unique:一維陣列去重

基本用法

$arr = [3, 1, 2, 3, 4, 1, 5];
$unique = array_unique($arr); // [0=>3, 1=>1, 2=>2, 4=>4, 6=>5]
// 同樣保留首次出現的鍵名

效能對比:foreach + in_array vs array_unique

$arr = array_merge(range(1,100), range(1,100)); // 200 元素,重複度 50%

// 方法 1:foreach + in_array
$t1 = microtime(true);
$res1 = [];
foreach ($arr as $v) { if (!in_array($v, $res1)) $res1[] = $v; }
$t1 = microtime(true) - $t1;

// 方法 2:array_unique
$t2 = microtime(true);
$res2 = array_unique($arr);
$t2 = microtime(true) - $t2;

echo "foreach: $t1 秒\nunique: $t2 秒\n";
// 結論:資料量 < 1000 差異微小;> 10000 且重複度高時 array_unique 明顯更快

二維陣列去重:通用函式

原生 array_unique 遇到陣列元素會拋出 Warning。解法:將子陣列序列化為字串去重,再還原。

/**
 * 二維陣列去重(保留鍵名可選)
 * @param array  $arr2D    二維陣列
 * @param bool   $keepKeys 是否保留一層鍵名
 * @param bool   $keepSubKeys 是否保留二層鍵名(需所有子陣列鍵名相同)
 * @return array
 */
function array2dUnique(array $arr2D, bool $keepKeys = false, bool $keepSubKeys = true): array {
    // 1. 降維:子陣列 -> 字串
    $serialized = [];
    foreach ($arr2D as $k => $v) {
        $serialized[$k] = serialize($v); // 或 json_encode($v, JSON_UNESCAPED_UNICODE|JSON_SORT_KEYS)
    }

    // 2. 去重
    $uniqueSerial = array_unique($serialized);

    // 3. 還原
    $result = [];
    foreach ($uniqueSerial as $k => $s) {
        $newKey = $keepKeys ? $k : null;
        $val = unserialize($s); // 或 json_decode($s, true)
        if ($keepSubKeys) {
            $result[$newKey] = $val;
        } else {
            $result[$newKey] = array_values($val);
        }
    }
    return $result;
}

// 測試
$data = [
    'first'  => ['title' => 'A', 'date' => '2023-01-01'],
    'second' => ['title' => 'A', 'date' => '2023-01-01'], // 重複
    'third'  => ['title' => 'B', 'date' => '2023-01-02'],
];
print_r(array2dUnique($data, true));
/*
Array
(
    [first]  => Array ( [title] => A [date] => 2023-01-01 )
    [third]  => Array ( [title] => B [date] => 2023-01-02 )
)
*/

進階:以特定欄位去重(如 id 去重)

function uniqueByField(array $arr, string $field): array {
    $seen = [];
    return array_filter($arr, function($item) use ($field, &$seen) {
        $val = $item[$field] ?? null;
        if ($val === null || isset($seen[$val])) return false;
        $seen[$val] = true;
        return true;
    });
}

$users = [
    ['id'=>1, 'name'=>'A'],
    ['id'=>2, 'name'=>'B'],
    ['id'=>1, 'name'=>'A dup'], // 重複 id
];
print_r(uniqueByField($users, 'id'));
// 保留首筆 id=1

總結速查

需求函式/方法注意
移除空值/假值array_filter($arr)保留鍵名,配合 array_values 重排
自定義邏輯過濾array_filter($arr, fn($v)=>...)可用 ARRAY_FILTER_USE_KEY/BOTH
一維去重array_unique($arr)大陣列效能優於 foreach+in_array
二維去重(整行比對)array2dUnique($arr)內部用 serialize/json,支援巢狀結構
指定欄位去重uniqueByField($arr, 'id')保留首次出現,適用業務主鍵
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved