PHP | 複数の配列、連想配列、多次元配列の結合方法とサンプルまとめ

Code:

$result = array_merge(配列, 配列[, 配列 ...]);
$result = 配列 + 配列;
$result = array_merge_recursive(配列, 配列[, 配列 ...]);
配列、連想配列、多次元配列の結合方法にはいくつかの方法があります。
それぞれ似たような挙動をするものの、渡す配列によって、結合したり、上書きしたり、返される配列が変わってきます。
今回は、色々な配列を渡したサンプルを元に、配列の結合方法を紹介していきたいと思います。

    もくじ

  1. 使い方
  2. 他の書き方
  3. 注意点
  4. まとめ

使い方

一次元の単純配列の結合

Code:

$a = [1, 2];
$b = [3, 4, 5];
$c = array_merge($a, $b);
$d = $a + $b;
$e = array_merge_recursive($a, $b);

Result:

// $c = array_merge($a, $b);
// $e = array_merge_recursive($a, $b);
array(5) {
  [0]=>
  int(1)
  [1]=>
  int(2)
  [2]=>
  int(3)
  [3]=>
  int(4)
  [4]=>
  int(5)
}
array_mergearray_merge_recursiveどちらも同じ結果となります。
1つ目の配列の後ろに2つ目の配列を結合、一番理解しやすい形の結合だと思います。
2つ以上の結合も可能です。

Result:

// $d = $a + $b;
array(3) {
  [0]=>
  int(1)
  [1]=>
  int(2)
  [2]=>
  int(5)
}
プラス演算子で配列の結合を行うと、重複した最初のkeyが優先され、後の配列のkeyは無視されてしまいます。
サンプルでは重複したkeyの「0、1」は最初の配列が優先され、「2」は重複していないので、そのまま後ろへと連結されます。
おそらくこの仕様を求めてプラス演算子を利用することは少ないと思うので、配列の連結にプラス演算子を用いる場合は注意しましょう。

keyが重複しない連想配列の結合

Code:

$a = [
    'a' => 1,
    'b' => 2,
];
$b = [
    'c' => 3,
    'd' => 4,
    'e' => 5
];
$c = array_merge($a, $b);
$d = $a + $b;
$e = array_merge_recursive($a, $b);

Result:

array(5) {
  ["a"]=>
  int(1)
  ["b"]=>
  int(2)
  ["c"]=>
  int(3)
  ["d"]=>
  int(4)
  ["e"]=>
  int(5)
}
keyの重複のない連想配列を連結する場合は、どの方法を用いても同じ結果が得られます。

keyが重複する連想配列の結合

Code:

$a = [
    'a' => 1,
    'b' => 2,
];
$b = [
    'a' => 3,
    'b' => 4,
    'c' => 5
];
$c = array_merge($a, $b);
$d = $a + $b;
$e = array_merge_recursive($a, $b);
keyの重複する連想配列の場合は、全ての処理で結果が変わってしまうので注意が必要です。

Result:

// $c = array_merge($a, $b);
array(3) {
  ["a"]=>
  int(3)
  ["b"]=>
  int(4)
  ["c"]=>
  int(5)
}
array_mergeでは、配列をプラス演算子で連結する時とは逆の結果、後ろに記載したkeyで上書きされます。
サンプルでは「a、b」と重複したkeyが、後半の配列のkeyで上書きされ、新しく出現した「c」に関しては、そのまま連結されます。

Result:

// $d = $a + $b;
array(3) {
  ["a"]=>
  int(1)
  ["b"]=>
  int(2)
  ["c"]=>
  int(5)
}
プラス演算子では、keyが数値、文字列、どちらも変わらずに、配列をプラス演算子で連結する時と同様の結果となります。

Result:

// $e = array_merge_recursive($a, $b);
array(3) {
  ["a"]=>
  array(2) {
    [0]=>
    int(1)
    [1]=>
    int(3)
  }
  ["b"]=>
  array(2) {
    [0]=>
    int(2)
    [1]=>
    int(4)
  }
  ["c"]=>
  int(5)
}
array_merge_recursiveでは、重複したkeyは配列として返されます。
重複のなかったkeyは、元の値がそのまま返ります。
配列となるのは、keyが文字列の場合だけなので、注意が必要です。

keyが浮動小数点数の連想配列の結合

Code:

$a = [
    1.1 => 1.2,
    2.1 => 2.2
];
$b = [
    1.1 => 4.2,
    2.1 => 5.2,
    3.1 => 6.2
];
$c = array_merge($a, $b);
$d = $a + $b;
$e = array_merge_recursive($a, $b);

Result:

// $c = array_merge($a, $b);
// $e = array_merge_recursive($a, $b);
array(5) {
  [0]=>
  float(1.2)
  [1]=>
  float(2.2)
  [2]=>
  float(4.2)
  [3]=>
  float(5.2)
  [4]=>
  float(6.2)
}

// $d = $a + $b;
array(3) {
  [1]=>
  float(1.2)
  [2]=>
  float(2.2)
  [3]=>
  float(6.2)
}
連想配列のkeyが、浮動小数点数の場合は一次元の単純配列として処理されてしまいます。
key浮動小数点数を文字列にキャストしておくと連想配列として処理することも可能です。
ただ、ややこしいので浮動小数点数keyにするのは避けるべきでしょう。

配列と連想配列の結合

Code:

$a = [
    'a' => 1,
    'b' => 2,
];
$b = [
    3,
    4,
    5
];
$c = array_merge($a, $b);
$d = $a + $b;
$e = array_merge_recursive($a, $b);

Result:

array(5) {
  ["a"]=>
  int(1)
  ["b"]=>
  int(2)
  [0]=>
  int(3)
  [1]=>
  int(4)
  [2]=>
  int(5)
}
結合する配列が、連想配列と一次元の単純配列でも、keyを基準とした連結処理に変わりはありません。
サンプルでは、keyの重複がないので、keyが重複しない連想配列の結合と同様の結果となります。

多次元配列の結合

Code:

$a = [
    'a' => [1],
    'b' => 2,
];
$b = [
    'a' => 3,
    'b' => [4, 40],
    'c' => 5
];

$c = array_merge($a, $b);
$d = $a + $b;
$e = array_merge_recursive($a, $b);

Result:

// $c = array_merge($a, $b);
array(3) {
  ["a"]=>
  int(3)
  ["b"]=>
  array(2) {
    [0]=>
    int(4)
    [1]=>
    int(40)
  }
  ["c"]=>
  int(5)
}

// $d = $a + $b;
array(3) {
  ["a"]=>
  array(1) {
    [0]=>
    int(1)
  }
  ["b"]=>
  int(2)
  ["c"]=>
  int(5)
}

// $e = array_merge_recursive($a, $b);
array(3) {
  ["a"]=>
  array(2) {
    [0]=>
    int(1)
    [1]=>
    int(3)
  }
  ["b"]=>
  array(3) {
    [0]=>
    int(2)
    [1]=>
    int(4)
    [2]=>
    int(40)
  }
  ["c"]=>
  int(5)
}
結合する配列が、多次元配列でも、keyを基準とした連結処理に変わりはありません。
サンプルでは、keyの重複しているので、keyが重複する連想配列の結合と同様の結果となります。

他の書き方

foreachで結合

Code:

$a = [
    'a' => 1,
    'b' => 2,
];
$b = [
    'c' => 3,
    'd' => 4,
    'e' => 5
];
$c = [];
foreach ($a as $k => $v) {
    $c[] = $v;
}
foreach ($b as $k => $v) {
    $c[] = $v;
}

Result:

array(5) {
  [0]=>
  int(1)
  [1]=>
  int(2)
  [2]=>
  int(3)
  [3]=>
  int(4)
  [4]=>
  int(5)
}
効率的ではありませんが、foreachを使って全ての要素を順に追加していけば同じ結果が得られます。
重複した場合は値となる数値を加算していきたい、特定のkeyだけ除外して追加したい、など、特殊な条件がある場合は、array_mergeプラス演算子では実現できないので、冗長になるのを覚悟してforeachを使いましょう。

注意点

空またはNULLのkeyを持つ配列の結合

Code:

$a = [
    null => 'a',
];
$b = [
    '' => 'b',
];
$c = array_merge($a, $b);
$d = $a + $b;
$e = array_merge_recursive($a, $b);

Result:

// $c = array_merge($a, $b);
array(1) {
  [""]=>
  string(1) "b"
}

// $d = $a + $b;
array(1) {
  [""]=>
  string(1) "a"
}

// $e = array_merge_recursive($a, $b);
array(1) {
  [""]=>
  array(2) {
    [0]=>
    string(1) "a"
    [1]=>
    string(1) "b"
  }
}
配列のkeyに「空文字」や「NULL」がある場合、同一のkeyと判断されてしまいます。
同一のkeyがある場合の処理は、keyが重複する連想配列の結合でも説明した通り、全て違う結果となります。
var_dump(null == ”);が、trueと判定されるのと同じ理由だと思います。
keyが「空文字」や「NULL」となりそうな場合は注意しましょう。

まとめ

今回は「array_merge」「プラス演算子」「array_merge_recursive」を用いた配列の結合方法を紹介しました。
渡す配列によって、それぞれの関数で結果が変わってくるので、注意しましょう。
ややこしいのでforeachで連結してしまうのも一つの手だとは思います(冗長になってしまいがちですが)。