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

PHP 多維數組去重:基於鍵值完整匹配的高效實現

     編輯:PHP 相關知識

處理多維數組去重時,array_unique() 僅支持一維數組,且基於字符串比較。針對多維關聯數組(如 API 返回的記錄集),需自定義比較邏輯。

場景示例:合併兩個書單並去重

$json = '{
  "rec_items": [
    {"gid": 6326585, "novel_name": "莽荒紀", "author": "我吃西紅柿"},
    {"gid": 6109786, "novel_name": "絕世唐門", "author": "唐家三少"}
  ],
  "cate_book_items": [
    {"gid": 6326585, "novel_name": "莽荒紀", "author": "我吃西紅柿"}, // 重複
    {"gid": 10645516, "novel_name": "完美世界", "author": "辰東"}
  ]
}';

$data = json_decode($json, true);
$merged = array_merge_recursive($data['rec_items'], $data['cate_book_items']);
// $merged 包含 4 個元素,其中 1 個重複

去重函數實現(保留首次出現順序)

function multiArrayUnique(array $array): array {
    $result = [];
    $seen = []; // 存儲已見鍵值簽名
    
    foreach ($array as $key => $value) {
        // 生成唯一簽名:排序鍵 + 序列化值(確保順序無關)
        ksort($value);
        $signature = serialize($value);
        
        if (!isset($seen[$signature])) {
            $seen[$signature] = true;
            $result[$key] = $value; // 保留原鍵或重新索引
        }
    }
    return $result;
}

// 使用
$unique = multiArrayUnique($merged);
// 結果:3 個元素,重複的 gid=6326585 被移除

進階版:指定字段去重(如按 gid 去重)

function multiArrayUniqueByField(array $array, string $field): array {
    $result = [];
    $seen = [];
    
    foreach ($array as $item) {
        if (!isset($item[$field])) continue; // 跳過無該字段項
        
        $key = $item[$field];
        if (!isset($seen[$key])) {
            $seen[$key] = true;
            $result[] = $item;
        }
    }
    return $result;
}

// 使用:按 gid 去重
$unique = multiArrayUniqueByField($merged, 'gid');

性能對比與選擇指南

方法時間複雜度適用場景備註
in_array() 遍歷檢查O(n²)小數據集 (<1000)簡單但慢
serialize() + isset()O(n)完整結構去重、鍵順序不敏感推薦通用方案
指定字段 isset($seen[$key])O(n)業務主鍵去重(如 ID、SKU)最快、語義最清晰
array_unique() (SORT_REGULAR)O(n log n)一維數組、標量值PHP 7.2+ 支持多維但不可靠

大數據量優化策略

  • **分塊處理**:array_chunk($data, 10000) 分批去重再合併
  • **資料庫層面去重**:SELECT DISTINCT ON (gid) ... (PostgreSQL) 或 GROUP BY gid
  • **流式處理**:生成器逐行讀取、判重、輸出,避免全量載入內存
  • **雜湊索引**:預計算 md5(serialize($item)) 作為鍵,比 serialize() 更快

常見陷阱

  1. 鍵名大小寫敏感: ['GID'=>1] vs ['gid'=>1] 視為不同,預處理 array_change_key_case()
  2. 數值/字符串等價: 123 vs '123' 序列化不同,預處理類型統一
  3. 浮點數精度: 0.1+0.2 序列化不穩定,金額字段建議存整數分
  4. 對象/資源類型: 無法直接序列化,需實現 __serialize() 或轉數組

選擇合適策略:業務主鍵去重用字段法,結構去重用序列化簽名法,大數據推流式/資料庫層面解決。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved