配列の統合時の先勝ち後勝ちの話
起
2つの配列$a
と$b
をマージした結果として$expected
のようなものが欲しくて‥
<?php $a = array( '11', 'k2' => '22', 'k4' => '44', 'k6' => '66', 'k8' => '88', ); $b = array( '111', 'k2' => '222', 'k3' => '333', 'k5' => '555', 'k7' => '777', ); $expected = array ( '111', 'k2' => '222', 'k4' => '44', 'k6' => '66', 'k8' => '88', 'k3' => '333', 'k5' => '555', 'k7' => '777', );
+
演算子やarray_merge
関数を使ってみるが‥
<?php $a = array( '11', 'k2' => '22', 'k4' => '44', 'k6' => '66', 'k8' => '88', ); $b = array( '111', 'k2' => '222', 'k3' => '333', 'k5' => '555', 'k7' => '777', ); $expected = array ( '111', 'k2' => '222', 'k4' => '44', 'k6' => '66', 'k8' => '88', 'k3' => '333', 'k5' => '555', 'k7' => '777', ); printf("===%s===\n", 'expected'); var_dump($expected); printf("===%s===\n", '$a + $b'); var_dump($a + $b); printf("===%s===\n", '$b + $a'); var_dump($b + $a); printf("===%s===\n", 'array_merge($a, $b)'); var_dump(array_merge($a, $b)); printf("===%s===\n", 'array_merge($b, $a)'); var_dump(array_merge($b, $a));
何かが違う‥
===expected=== array(8) { [0]=> string(3) "111" ["k2"]=> string(3) "222" ["k4"]=> string(2) "44" ["k6"]=> string(2) "66" ["k8"]=> string(2) "88" ["k3"]=> string(3) "333" ["k5"]=> string(3) "555" ["k7"]=> string(3) "777" } ===$a + $b=== array(8) { [0]=> string(2) "11" ["k2"]=> string(2) "22" ["k4"]=> string(2) "44" ["k6"]=> string(2) "66" ["k8"]=> string(2) "88" ["k3"]=> string(3) "333" ["k5"]=> string(3) "555" ["k7"]=> string(3) "777" } ===$b + $a=== array(8) { [0]=> string(3) "111" ["k2"]=> string(3) "222" ["k3"]=> string(3) "333" ["k5"]=> string(3) "555" ["k7"]=> string(3) "777" ["k4"]=> string(2) "44" ["k6"]=> string(2) "66" ["k8"]=> string(2) "88" } ===array_merge($a, $b)=== array(9) { [0]=> string(2) "11" ["k2"]=> string(3) "222" ["k4"]=> string(2) "44" ["k6"]=> string(2) "66" ["k8"]=> string(2) "88" [1]=> string(3) "111" ["k3"]=> string(3) "333" ["k5"]=> string(3) "555" ["k7"]=> string(3) "777" } ===array_merge($b, $a)=== array(9) { [0]=> string(3) "111" ["k2"]=> string(2) "22" ["k3"]=> string(3) "333" ["k5"]=> string(3) "555" ["k7"]=> string(3) "777" [1]=> string(2) "11" ["k4"]=> string(2) "44" ["k6"]=> string(2) "66" ["k8"]=> string(2) "88" }
まぁ$b + $a
は、内容的には合っているんだけど、ベースは$a
で後勝ちしたいのでちょっと違和感‥
array_merge
は惜しいが違うし‥
承
見た目の順番が同じものが得られないかな‥と思い、意味的にはこんな感じで、
<?php $a = array( '11', 'k2' => '22', 'k4' => '44', 'k6' => '66', 'k8' => '88', ); $b = array( '111', 'k2' => '222', 'k3' => '333', 'k5' => '555', 'k7' => '777', ); printf("===%s===\n", 'foreach'); $r = $a; foreach ($b as $k => $v) { $r[$k] = $v; } var_dump($r);
こんな感じの結果が得られるやつ。
===foreach=== array(8) { [0]=> string(3) "111" ["k2"]=> string(3) "222" ["k4"]=> string(2) "44" ["k6"]=> string(2) "66" ["k8"]=> string(2) "88" ["k3"]=> string(3) "333" ["k5"]=> string(3) "555" ["k7"]=> string(3) "777" }
転
で、いろいろ試行錯誤して、
<?php $a = array( '11', 'k2' => '22', 'k4' => '44', 'k6' => '66', 'k8' => '88', ); $b = array( '111', 'k2' => '222', 'k3' => '333', 'k5' => '555', 'k7' => '777', ); printf("===%s===\n", 'array_merge(array_diff($a, array_intersect_key($a, $b)), $b)'); $r = array_merge(array_diff($a, array_intersect_key($a, $b)), $b); var_dump($r);
で、見た目の順番は違うけど同じ結果が得られた。
array(8) { ["k4"]=> string(2) "44" ["k6"]=> string(2) "66" ["k8"]=> string(2) "88" [0]=> string(3) "111" ["k2"]=> string(3) "222" ["k3"]=> string(3) "333" ["k5"]=> string(3) "555" ["k7"]=> string(3) "777" }
結
‥と喜んでいたら、array_replace
なるものがあった件。
<?php $a = array( '11', 'k2' => '22', 'k4' => '44', 'k6' => '66', 'k8' => '88', ); $b = array( '111', 'k2' => '222', 'k3' => '333', 'k5' => '555', 'k7' => '777', ); printf("===%s===\n", 'array_replace($a, $b)'); $r = array_replace($a, $b); var_dump($r);
見た目の順番まで期待通り。
===array_replace($a, $b)=== array(8) { [0]=> string(3) "111" ["k2"]=> string(3) "222" ["k4"]=> string(2) "44" ["k6"]=> string(2) "66" ["k8"]=> string(2) "88" ["k3"]=> string(3) "333" ["k5"]=> string(3) "555" ["k7"]=> string(3) "777" }
まとめ
私が知る限りの配列の「足し算」をする演算/関数の違いの簡単なまとめ。
演算/関数 | 数値インデックス | 文字列インデックス |
---|---|---|
$a + $b |
先勝ち | 先勝ち |
array_merge($a, $b) |
続きから追記 | 後勝ち |
array_replace($a, $b) |
後勝ち | 後勝ち |
知らない事がまだまだ多いな‥