array_mergeは添字を振りなおす
$left = [
2 => '2',
1000 => '1000'
];
$right = [
5 => '5',
2000 => '2000'
];
$result = array_merge($left,$right);
とした場合、この連想配列のarray_merge
の結果は、連想配列が維持されません。
array (
0 => '2',
1 => '1000',
2 => '5',
3 => '2000',
)
になります。
同様に引っかかった人が多いのか、array_merge
のドキュメントを読んでみると、このことが念入りに書いてあります。
「入力配列の中にある数値添字要素の添字の数値は結果の配列ではゼロから始まる連続した数値に置き換えられます」。
なんでや! by 犠牲者N号
ちなみにインデックスがString型でも、数字の場合はphpが勝手に数字として解釈してしまい、添字の振り直しが行われます。
$left = [
'2' => '2',
'1000' => '1000'
];
$right = [
'5' => '5',
'2000' => '2000'
];
これはアウトです。
足し算での結合の場合は数字の振り直しはない
足し算で結合すれば振り直しは行われないようです。
$left = [
2 => '2',
1000 => '1000'
];
$right = [
5 => '5',
2000 => '2000'
];
$result = $left + $right;
この結果は
array (
2 => '2',
1000 => '1000',
5 => '5',
2000 => '2000',
)
になります。
結論
というわけで連想配列の数字のindexを維持して結合したい際は足し算で結合しましょう。
逆にもし、振り直しをしたいユースケースの場合は足し算を使わずにarray_merge
を使うのがよいと思います。
余談ですが、PHP7.4移行は[...$left,...$right]
のようにスプレッド構文での結合方法が存在しますが、
この場合も連想配列のキーが数字の場合は添字を振りなおします。
なお、連想配列がキーがString型の場合はそもそもスプレッド構文を用いた結合ができません。
知らないと積みポイントなので備忘録化。