PHP兩陣列相加少了一筆:+與array_merge怎麼選

把兩批文章標題放進陣列,用$left + $right合起來,結果右邊第一筆不見了。PHP陣列的加號是按鍵名做聯集,不是把所有值接到後面。兩邊有相同鍵名時,左邊的值會留下,右邊對應的值會被忽略。

兩個列表都從0開始,第一個鍵就撞上了

以下每段都是獨立PHP範例,可各自存成.php檔執行。註解列出預期輸出,資料只是示例字串。

<?php
$left = ['header', 'footer'];
$right = ['sidebar'];

echo json_encode($left + $right), PHP_EOL;
// ["header","footer"]

echo json_encode(array_merge($left, $right)), PHP_EOL;
// ["header","footer","sidebar"]

left的鍵是0、1;right的鍵也是0。因此,sidebar與header搶的是同一個鍵,加號保留左邊的header,並不是按文字內容去除重複。若只是要把兩批列表依序接起來,array_merge會保留三個值,並把整數鍵從0重新編號。

字串鍵相同時,兩種寫法的優先順序相反

<?php
$left = ['color' => 'blue', 'rows' => 12];
$right = ['color' => 'red', 'cache' => true];

echo json_encode($left + $right), PHP_EOL;
// {"color":"blue","rows":12,"cache":true}

echo json_encode(array_merge($left, $right)), PHP_EOL;
// {"color":"red","rows":12,"cache":true}

加號保留左邊color的blue;array_merge則由後面的red覆蓋前面的值。右邊獨有的cache,在兩種結果裡都會出現。合併網站設定時,先決定同鍵衝突要由誰優先,再選寫法;交換左右位置也會改變結果。

這個例子只處理一層鍵值。巢狀設定裡若還有陣列,不能直接把它當成逐層遞迴合併。

數字是文章ID時,不要順手重編鍵名

<?php
$left = [101 => 'Article A'];
$right = [202 => 'Article B'];

echo json_encode($left + $right), PHP_EOL;
// {"101":"Article A","202":"Article B"}

echo json_encode(array_merge($left, $right)), PHP_EOL;
// ["Article A","Article B"]

這次的101和202假設是文章ID,不是列表位置。加號會保留這兩個鍵;array_merge則把它們改成0與1。若後續要用文章ID取值,重編鍵名就會破壞原來的查找方式。

不過,加號也不是無條件保留所有資料:兩批若同時含有101,仍只會留下左邊那筆。上面的JSON輸出是為了方便看結果;需要核對PHP原本的鍵與型別時,也可以用var_export或var_dump。

先回答資料代表什麼,再選合併方法

  • 資料是依序顯示的列表,希望兩批值都接上:用array_merge,接受整數鍵重新編號。
  • 鍵是固定識別碼,希望保留鍵名,且同鍵時左邊優先:可用加號聯集;同鍵右側資料會被捨棄。
  • 資料是一層字串鍵設定,希望後面的設定覆蓋前面:array_merge符合這個優先順序。

查「合併後少一筆」時,先把兩邊的鍵列出來,不要只盯著值。若資料筆數與ID都必須完整保留,就要明確處理同鍵衝突,不能靠換一個合併符號替你決定。

參考資料

原文鏈接:https://wntheme.com/php-array-union-plus-array-merge-keys/,轉載請註明出處。
0

評論0

顯示驗證碼
沒有帳號?註冊  忘記密碼?