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

PHP 數值鍵數組合併去重終極指南:array_merge vs + 運算符深度對比

     編輯:PHP 相關知識

PHP 數組合併看似簡單,實則暗藏「鍵名重建」與「值覆蓋」的雙重陷阱。本文通過 6 組對比實驗,徹底釐清 array_merge() 與 + 運算符在數值鍵、字符串鍵、混合鍵下的行為差異,並提供一行代碼實現「數值鍵數組合併去重」的最佳實踐。

核心差異速查表

場景array_merge()+ 運算符
數值鍵相同不覆蓋,重新索引追加 (0,1,2,3...)保留首次出現,拋棄後續
字符串鍵相同後覆蓋前保留首次出現,拋棄後續
鍵名類型不同 (0 vs '0')視為不同鍵,均保留並重新索引PHP 視為同鍵,保留首次

六組實驗鐵證如山

實驗 1:純數值索引數組

$a = ['a', 'b'];        // [0=>a, 1=>b]
$b = ['c', 'd'];        // [0=>c, 1=>d]

var_dump($a + $b);      // [0=>a, 1=>b]          ← 保留首個
var_dump(array_merge($a, $b)); // [0=>a, 1=>b, 2=>c, 3=>d] ← 重新索引追加

實驗 2:顯式數值鍵重複

$a = [0=>'a', 1=>'b'];
$b = [0=>'c', 1=>'b'];  // 鍵 0,1 重複

$a + $b;                // [0=>a, 1=>b]
array_merge($a, $b);    // [0=>a, 1=>b, 2=>c, 3=>b]  ← 鍵 1 的值 'b' 被保留兩次!

實驗 3:字符串鍵 '0' vs 數值鍵 0

$a = ['a', 'b'];              // [0=>a, 1=>b]
$b = ['0'=>'c', 1=>'b'];      // 字符串 '0' 和數值 1

$a + $b;                      // [0=>a, 1=>b]     ← '0' 被視為 0,拋棄 'c'
array_merge($a, $b);          // [0=>a, 1=>b, 2=>c, 3=>b] ← 視為不同鍵,重新索引

實驗 4:全字符串數值鍵

$a = [0=>'a', 1=>'b'];
$b = ['0'=>'c', '1'=>'b'];

$a + $b;                      // [0=>a, 1=>b]
array_merge($a, $b);          // [0=>a, 1=>b, 2=>c, 3=>b]

一行代碼實現:數值鍵數組合併去重(保留順序)

需求:合併兩個數值索引數組,去除重複值,保留首次出現順序,重新建立連續索引。

function mergeNumericArraysUnique(array $arr1, array $arr2): array {
    return array_keys(array_flip($arr1) + array_flip($arr2));
}

// 測試
$arr1 = ['aa', 'bb', 'cc'];
$arr2 = ['aa2', 'bb', 'cc2'];

print_r(mergeNumericArraysUnique($arr1, $arr2));
/*
Array
(
    [0] => aa
    [1] => bb
    [2] => cc
    [3] => aa2
    [4] => cc2
)
*/

原理解析

  1. array_flip($arr1):值變鍵,鍵變值 → ['aa'=>0, 'bb'=>1, 'cc'=>2],自動去重(後值覆蓋前鍵,但我們只關心鍵名)
  2. + 運算符合併:保留首次出現的鍵,即 $arr1 中值優先
  3. array_keys():提取鍵名 → 即原數組值,並自動生成連續數值索引

進階場景與變體

場景 A:以第二個數組優先去重

array_keys(array_flip($arr2) + array_flip($arr1));  // 交換順序

場景 B:保留原鍵名不重建索引(關聯數組去重)

array_flip(array_flip($arr1) + array_flip($arr2));  // 不用 array_keys

場景 C:多數組合併去重

function mergeMultipleUnique(array ...$arrays): array {
    $flipped = [];
    foreach ($arrays as $arr) {
        $flipped += array_flip($arr);  // 依次合併,首個優先
    }
    return array_keys($flipped);
}

性能對比:flip+ 鍵法 vs 迴圈檢查法


// 基準測試:10,000 元素數組,50% 重複
$arr1 = range(1, 10000);
$arr2 = range(5000, 15000);

// 方法 1:flip + 鍵 (本文推薦)
$start = microtime(true);
$result1 = array_keys(array_flip($arr1) + array_flip($arr2));
echo "flip+keys: " . (microtime(true) - $start) * 1000 . " ms\n";  // ~2.1 ms

// 方法 2:array_unique + array_merge
$start = microtime(true);
$result2 = array_unique(array_merge($arr1, $arr2));
echo "unique+merge: " . (microtime(true) - $start) * 1000 . " ms\n";  // ~3.8 ms

// 方法 3:迴圈 in_array 檢查
$start = microtime(true);
$result3 = $arr1;
foreach ($arr2 as $v) {
    if (!in_array($v, $result3)) $result3[] = $v;
}
echo "loop+in_array: " . (microtime(true) - $start) * 1000 . " ms\n";  // ~180 ms (O(n²) 災難)

避坑指南總結

  1. 默認選 array_merge():語義明確「合併」,配合 array_values() 重建索引最安全
  2. 需「首個優先去重」用 +:但記住它不重建索引,後續常需 array_values()
  3. 數值鍵去重合併:array_keys(array_flip($a) + array_flip($b)) 兼具性能與語義
  4. 嚴禁在循環中用 in_array:大數據量下性能指數級下降
  5. 字符串鍵 '0' ≠ 數值鍵 0:array_merge 視為不同,+ 視為相同,極易導致邏輯 Bug

總結

PHP 數組合併的核心複雜度在於「鍵名類型轉換規則」與「重複值處理策略」的耦合。掌握 array_flip + + 運算符的組合拳,能以 O(n) 時間複雜度優雅解決 90% 的數值鍵數組去重合併需求,是每個 PHP 開發者必備的工具箱技能。

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