PHPの配列結合まとめ

## 数値添字と文字列添字について

配列のキーには int型 と string型 が存在します。
ここではキーが int型 であるものを数値添字，string型 であるものを文字列添字と呼びます。
また，文字列添字配列のことを連想配列と呼びます。

### 数値添字配列

```php
// どちらも数値添字配列です
$a = [1, 2, 3, 'hello'];
$b = [0 => 'a', '3' => 30, 100 => 70, 'world'];

/*
Array
(
    [0] => 1
    [1] => 2
    [2] => 3
    [3] => hello
)

Array
(
    [0] => a
    [3] => 30
    [100] => 70
    [101] => world
)
*/
```

### 文字列添字配列（連想配列）

```php
// 文字列添字配列（連想配列）です
$a = ['name' => 'Bob', 'age' => 70, '1x' => 'xyz', '02' => 2];

/*
Array
(
    [name] => Bob
    [age] => 70
    [1x] => xyz
    [02] => 2
)
*/
```

キーの型の決まり方には注意が必要です。

「1」「'1'」「1.2」「01」→ int型
「'01'」「'1.2'」「'name'」→ string型

意図しない動作を避けるために，できるだけ文字列添字には数値を入れない方が良いかもしれません。

## 本題

添字について説明したのでここからは配列の結合方法を紹介します。

## 数値添字配列 同士

### array_merge

```php
$a = [1, 2, 3, 'hello'];
$b = [7, 8, 9, 'world', 10];

print_r(array_merge($a, $b));
```

```php
Array
(
    [0] => 1
    [1] => 2
    [2] => 3
    [3] => hello
    [4] => 7
    [5] => 8
    [6] => 9
    [7] => world
    [8] => 10
)
```

数値添字に重複があっても関係なく全ての要素を追加する。その後に添字を0から振り直す。

### array_replace

```php
$a = [1, 2, 3, 'hello'];
$b = [7, 8, 9, 'world', 10];

print_r(array_replace($a, $b));
```

```php
Array
(
    [0] => 7
    [1] => 8
    [2] => 9
    [3] => world
    [4] => 10
)
```

数値添字が重複した要素は，***後***の配列要素で上書きする。

### 結合演算子

```php
$a = [1, 2, 3, 'hello'];
$b = [7, 8, 9, 'world', 10];
print_r($a + $b);
```

```php
Array
(
    [0] => 1
    [1] => 2
    [2] => 3
    [3] => hello
    [4] => 10
)
```

数値添字が重複した要素は，***前***の配列要素を維持する（上書きしない）。

### Spread Operator（PHP7.4以降）

```php
$a = [1, 2, 3, 'hello'];
$b = [7, 8, 9, 'world', 10];

print_r([...$a, ...$b]);
```

```php
Array
(
    [0] => 1
    [1] => 2
    [2] => 3
    [3] => hello
    [4] => 7
    [5] => 8
    [6] => 9
    [7] => world
    [8] => 10
)
```

array_merge と同じ。
※ Spread Operator は数値添字配列でしか使えません。

##  連想配列 同士

### array_merge

```php
$a = ['name' => 'Bob', 'age' => 70];
$b = ['name' => 'Michel', 'country' => 'US'];

print_r(array_merge($a, $b));
```

```php
Array
(
    [name] => Michel
    [age] => 70
    [country] => US
)
```

文字列添字が重複したら，***後***の配列要素で上書きする。

### array_replace

```php
$a = ['name' => 'Bob', 'age' => 70];
$b = ['name' => 'Michel', 'country' => 'US'];

print_r(array_replace($a, $b));
```

```php
Array
(
    [name] => Michel
    [age] => 70
    [country] => US
)
```

文字列添字が重複したら，***後***の配列要素で上書きする。
※ array_merge と同じ。

### 結合演算子

```php
$a = ['name' => 'Bob', 'age' => 70];
$b = ['name' => 'Michel', 'country' => 'US'];

print_r($a + $b);
```

```php
Array
(
    [name] => Bob
    [age] => 70
    [country] => US
)
```

文字列添字が重複したら，***前***の配列要素を維持する（上書きしない）。

## 混合（数値添字配列 + 連想配列）同士

### array_merge

```php
$a = [1, 2, 3, 'name' => 'Bob', 'age' => 70];
$b = [7, 8, 9, 'name' => 'Michel', 'country' => 'US', 10, '2020' => 'PHP8'];

print_r(array_merge($a, $b));
```

```php
Array
(
    [0] => 1
    [1] => 2
    [2] => 3
    [name] => Michel
    [age] => 70
    [3] => 7
    [4] => 8
    [5] => 9
    [country] => US
    [6] => 10
    [7] => PHP8
)
```
数値添字の重複は関係なく全ての数値添字要素を追加する。その後に添字を0から振り直す。
文字列添字が重複した要素は，***後***の配列要素で上書きする。

### array_replace

```php
$a = [1, 2, 3, 'name' => 'Bob', 'age' => 70];
$b = [7, 8, 9, 'name' => 'Michel', 'country' => 'US', 10, '2020' => 'PHP8'];

print_r(array_replace($a, $b));
```

```php
Array
(
    [0] => 7
    [1] => 8
    [2] => 9
    [name] => Michel
    [age] => 70
    [country] => US
    [3] => 10
    [2020] => PHP8
)
```

数値添字と文字列添字どちらも，重複があれば***後***の配列要素で上書きする。

### 結合演算子

```php
$a = [1, 2, 3, 'name' => 'Bob', 'age' => 70];
$b = [7, 8, 9, 'name' => 'Michel', 'country' => 'US', 10, '2020' => 'PHP8'];

print_r($a + $b);
```

```php
Array
(
    [0] => 1
    [1] => 2
    [2] => 3
    [name] => Bob
    [age] => 70
    [country] => US
    [3] => 10
    [2020] => PHP8
)
```

数値添字と文字列添字どちらも，重複があっても***前***の配列要素を維持する（上書きしない）。

## 結論

***array_merge*** は，数値添字の重複は関係なく追加（キーは振り直す）するが，文字列添字の重複は後の配列要素で上書きする。

***array_replace*** は，キーの型に関わらず一貫して重複部分を上書きする（キーは振り直さない）。

***結合演算子***は，キーの型に関わらず一貫して重複部分を上書きせずに維持する（キーは振り直さない）。

※ 連想配列同士の結合では，array_merge と array_replace は同じ結果となる。

※ 数値添字配列同士の結合では，array_merge と Spread Operator は同じ結果となる。

## ざっくり理解

未定義のキーがあったら追加するのはどれも同じで...

***array_merge***　後優先で重複文字列は上書き。数値はとにかく追加して振り直す。
***array_replace***　後優先で上書き。
***結合演算子***　前優先で重複は無視。

## 参考

[配列結合演算子, array_merge, array_replace を徹底比較](https://qiita.com/mpyw/items/578e1a14879e679d2141)