萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 網路程式設計 >> PHP 程式設計

PHP array_unique 多維陣列去重完整解決方案

問題背景

array_unique() 僅支援一維陣列去重。對多維陣列直接使用會產生 Array to string conversion 警告且結果錯誤。

方案一:序列化法(適用關聯陣列)

function multiUnique(array $array): array {
    $serialized = array_map('serialize', $array);
    $unique = array_unique($serialized);
    return array_map('unserialize', $unique);
}

// 測試
$data = [
    ['id' => 1, 'name' => 'A'],
    ['id' => 2, 'name' => 'B'],
    ['id' => 1, 'name' => 'A'], // 重複
];
print_r(multiUnique($data));
// 保留鍵名:[0] => ['id'=>1,'name'=>'A'], [1] => ['id'=>2,'name'=>'B']

原理: 將子陣列序列化為字串 → 去重 → 反序列化還原。

方案二:鍵值對比較法(保留原始鍵名)

function assocUnique(array $array): array {
    $result = [];
    foreach ($array as $key => $value) {
        if (!in_array($value, $result, true)) { // 嚴格比較
            $result[$key] = $value;
        }
    }
    return $result;
}

方案三:通用二維陣列去重(支援保留鍵名、格式化)

function unique2D(array $array2D, bool $keepFirstKey = false, bool $keepSubKeys = true): array {
    // 記錄一級鍵名
    $firstKeys = $keepFirstKey ? array_keys($array2D) : null;
    // 記錄二級鍵名(假設所有子陣列鍵名相同)
    $subKeys = $keepSubKeys ? array_keys(end($array2D)) : null;
    
    // 降維:子陣列轉字串
    $temp = [];
    foreach ($array2D as $v) {
        $temp[] = implode(',', $v);
    }
    
    // 去重
    $temp = array_unique($temp);
    
    // 重組
    $output = [];
    foreach ($temp as $k => $v) {
        $newKey = $keepFirstKey ? $firstKeys[$k] : $k;
        if ($keepSubKeys) {
            $parts = explode(',', $v);
            foreach ($parts as $sk => $sv) {
                $output[$newKey][$subKeys[$sk]] = $sv;
            }
        } else {
            $output[$newKey] = explode(',', $v);
        }
    }
    return $output;
}

// 測試資料
$data = [
    'first'  => ['title' => '1111', 'date' => '2222'],
    'second' => ['title' => '1111', 'date' => '2222'], // 重複
    'third'  => ['title' => '2222', 'date' => '3333'],
];

print_r(unique2D($data, true));
// 保留 'first', 'third' 鍵名

效能比較

方法時間複雜度記憶體適用場景
序列化法O(n)中一般關聯陣列、結構不固定
in_array 比較O(n²)低小資料量、簡單結構
降維字串法O(n)中大量二維陣列、需保留鍵名

現代 PHP 寫法(PHP 7.4+)

unique()->values()->all(); // Laravel Collection
// 或純 PHP
$unique = array_values(array_unique($data, SORT_REGULAR));

注意事項

  • 陣列比較需鍵名順序一致(['a'=>1,'b'=>2] !== ['b'=>2,'a'=>1])
  • 巢狀深度 > 2 時建議改用序列化法或遞迴比較
  • 大資料量考慮使用雜湊值(md5(serialize($v)))作為索引
copyright © 萬盛學電腦網 all rights reserved