[PHP] 配列・連想配列の初期化、結合、追加


# 0. 環境
- PHPバージョン：5.5.14

# 1. 配列の初期化
## 1-1. 純粋な初期化
```php
$array = array();
```

## 1-2. 初期化＆代入
### 1-2-1. 1次元の配列
PHP においては「添字配列（キーが非負整数である配列）」と「連想配列（キーが文字列である配列）」の間に違いはなく、配列型は 1 つだけで、 同じ配列で整数のインデックスと文字列のインデックスを同時に使えます。

#### 添字配列の例

```php
$array = array('りんご', 'もも', 'なし'); // キーは0から順に0,1,2が割り振られる
```

#### 連想配列の例（キーを指定してセットする）

```php
$array = array('apple'=>'りんご', 'peach'=>'もも', 'pear'=>'なし');
```

#### 部分的にキーを指定することもできる

```php
$array = array('バナナ', 'apple'=>'りんご', 'peach'=>'もも', 'pear'=>'なし', 'みかん');
```

この時、中身を`print_r($array);`により確認すると

```
Array
(
    [0] => バナナ
    [apple] => りんご
    [peach] => もも
    [pear] => なし
    [1] => みかん
)
```

となっています。

#### `[]`を用いて初期化＆要素の追加
`[]`を用いて要素を追加すると、添字配列として要素が追加されます。

```php
$array[] = 'バナナ';
$array[] = 'みかん';
```

```
Array
(
    [0] => バナナ
    [1] => みかん
)
```

#### キーを指定して初期化＆要素の追加

```php
$array['banana'] = 'バナナ';
$array['mikan'] = 'みかん';
```

```
Array
(
    [banana] => バナナ
    [mikan] => みかん
)
```

#### 既にあるキー（or 添字）を指定すると上書きされる
```php
$array['banana'] = 'バナナ';
$array['mikan'] = 'みかん';
$array['banana'] = 'フィリピン';
$array['mikan'] = '愛媛';
```

```
Array
(
    [banana] => フィリピン
    [mikan] => 愛媛
)
```

【参考サイト】
▼公式HP。「配列」
http://php.net/manual/ja/language.types.array.php

### 1-2-2. 多次元配列
PHPでは、配列の要素の中を配列とすることもできます。これにより多次元配列を作成することができます。

#### 一気に代入

```php
$array = array('fruits'=>array('a'=>'orange', 'b'=>'banana'), 'numbers'=>array(1, 3, 5));
```

```
Array
(
    [fruits] => Array
        (
            [a] => orange
            [b] => banana
        )

    [numbers] => Array
        (
            [0] => 1
            [1] => 3
            [2] => 5
        )

)
```

#### 要素を1つずつ代入

```php
$array['tamura']['height'] = 170;
$array['tamura']['blood'] = 'A';
$array['tamura']['hobbies'] = array('soccer', 'tennis', 'mathematics');
$array['tanaka']['height'] = 165;
$array['tanaka']['blood'] = 'AB';
$array['tanaka']['hobbies'] = array('piano', 'golf');
```

```
Array
(
    [tamura] => Array
        (
            [height] => 170
            [blood] => A
            [hobbies] => Array
                (
                    [0] => soccer
                    [1] => tennis
                    [2] => mathematics
                )

        )

    [tanaka] => Array
        (
            [height] => 165
            [blood] => AB
            [hobbies] => Array
                (
                    [0] => piano
                    [1] => golf
                )

        )

)
```

# 2. 配列の結合・追加
配列の結合・追加には、

- 結合
  - `array_merge()`関数
  - `array_merge_recursive()`関数
  - `+`演算子
- 追加
  - `array_push()`関数
  - `[]`の利用

など様々な方法があります。

## 2-1. 配列の結合
### 2-1-1. `array_merge()`関数による配列結合
`array_merge()`関数の公式HPによる説明は、

- 前の配列の後ろに配列を追加することにより、ひとつまたは複数の配列の要素をマージし、得られた配列を返します。
- 入力配列が同じキー文字列を有していた場合、そのキーに関する後に指定された値が、前の値を上書きします。しかし、配列が同じ添字番号を有していても値は追記されるため、このようなことは起きません。
- 入力配列の中にある数値添字要素の添字の数値は、結果の配列ではゼロから始まる連続した数値に置き換えられます。

となっています。
下記の例をご覧ください。

```php
$array1 = array('color'=>'red', 10=>1, 0=>3);
$array1[] = 100;
$array2 = array('a', 'b', 'color'=>'green', 5);
$array = array_merge($array1, $array2);

print_r($array1);
print_r($array2);
print_r($array);
```

```
Array
(
    [color] => red
    [10] => 1
    [0] => 3
    [11] => 100
)
Array
(
    [0] => a
    [1] => b
    [color] => green
    [2] => 5
)
Array
(
    [color] => green
    [0] => 1
    [1] => 3
    [2] => 100
    [3] => a
    [4] => b
    [5] => 5
)
```

上記の例から、

- キーが文字列なら値が上書きされている
- キーが数値なら値は上書きされず、添字番号が振り直されて全て保持される
- 添字配列の添字番号は、「値が小さい順」ではなく「宣言された順」に保持されている
- 添字配列への要素追加（`$array1[] = 100;`）は、現存する最大添字番号の次（添字番号11）に追加される

などが確認できます。

【参考サイト】
▼公式HP。「array_merge」
http://php.net/manual/ja/function.array-merge.php

### 2-1-2. `array_merge_recursive()`関数による配列結合
`recursive`という英単語は「再帰的な」という意味を持つ形容詞です。
`array_merge_recursive()`関数の公式HPによる説明は、

- 一つ以上の配列の要素をマージし、前の配列の最後にもう一つの配列の値を追加します。マージした後の配列を返します。
- 入力配列が同じ文字列のキーを有している場合、マージした後の配列ではこれらのキーの値がひとつにまとめられます。この処理は再帰的に行われます。
- このため、値の一つが配列自体を指している場合、この関数は別の配列の対応するエントリもマージします。しかし、配列が同じ数値キーを有している場合、後の値は元の値を上書せず、追加されます。

となっています。
下記の例をご覧ください。

```php
$array1 = array('color'=>'red', 10=>1, 0=>3);
$array1[] = 100;
$array2 = array('a', 'b', 'color'=>'green', 5);
$array = array_merge_recursive($array1, $array2);

print_r($array1);
print_r($array2);
print_r($array);
```

```
Array
(
    [color] => red
    [10] => 1
    [0] => 3
    [11] => 100
)
Array
(
    [0] => a
    [1] => b
    [color] => green
    [2] => 5
)
Array
(
    [color] => Array
        (
            [0] => red
            [1] => green
        )

    [0] => 1
    [1] => 3
    [2] => 100
    [3] => a
    [4] => b
    [5] => 5
)
```

上記の例は、`2-1. array_merge()`で用いた配列と全く同じです。
これらを比較することにより、文字列キーが重複した場合

- `array_merge()`　→　値が上書きされる
- `array_merge_recursive()`　→　どちらも保持する（配列として保持）

という違いが見て取れます。

【参考サイト】
▼公式HP。「array_merge_recursive」
http://php.net/manual/ja/function.array-merge-recursive.php

### 2-1-3. `+`演算子による配列結合
`+`演算子による配列結合は、`array_merge()`や`array_merge_recursive()`と挙動が似ていますが、若干違います。
具体的には、キーが数字の場合、

- `array_merge()`、`array_merge_recursive()`　→　キーを振りなおして結合
- `+`演算子　→　キーはそのままで、重複した場合前の配列の値を残す

という違いがあります。
下記の例をご覧ください。

```php
$array1 = array('color'=>'red', 10=>1, 0=>3);
$array1[] = 100;
$array2 = array('a', 'b', 'color'=>'green', 5);
$array = $array1 + $array2;

print_r($array1);
print_r($array2);
print_r($array);
```

```
Array
(
    [color] => red
    [10] => 1
    [0] => 3
    [11] => 100
)
Array
(
    [0] => a
    [1] => b
    [color] => green
    [2] => 5
)
Array
(
    [color] => red
    [10] => 1
    [0] => 3
    [11] => 100
    [1] => b
    [2] => 5
)
```

配列結合の違いをまとめると、

||array_merge|array_merge_recursive|+演算子|
|:--|:--|:--|:--|
|キーが<br>数値|キー重複時、値は上書きされない。<br>添字番号が振り直されて全て保持される。|キー重複時、値は上書きされない。<br>添字番号が振り直されて全て保持される。|キー重複時、値は前の配列を残す。<br>添字番号の振り直しはされない。|
|キーが<br>文字列|キー重複時、値が上書きされる。|キー重複時、値が全て保持される。|キー重複時、値は前の配列を残す。|

【参考サイト】
▼PHPの配列結合
http://qiita.com/ukisoft/items/55e7c3142dc1388c8264
▼PHP の array_merge() や array_recursive() 等の違いをまとめました
http://www.tam-tam.co.jp/tipsnote/program/post4067.html

## 2-2. 配列の追加
### 2-2-1. `array_push()`関数による配列追加
```
array_push(配列, 追加する要素[, 追加する要素 ... ]);
```

`array_push()`関数は、第一引数の配列に第二引数以降の要素を追加していきます。
「添字配列」の最後の要素として追加される（キーが数値として追加される）。

```php
$array1 = array('color'=>'red', 10=>1, 0=>3);
$array2 = array('a', 'b', 'color'=>'green', 5);
print_r($array1);
print_r($array2);

array_push($array1, $array2);
print_r($array1);
```

```
Array
(
    [color] => red
    [10] => 1
    [0] => 3
)
Array
(
    [0] => a
    [1] => b
    [color] => green
    [2] => 5
)
Array
(
    [color] => red
    [10] => 1
    [0] => 3
    [11] => Array
        (
            [0] => a
            [1] => b
            [color] => green
            [2] => 5
        )

)
```

【参考サイト】
▼公式HP。「array_push」
http://php.net/manual/ja/function.array-push.php
▼PHPで連想配列にいろんな方法で追加させた時の挙動一覧
http://amanek0.blog.fc2.com/blog-entry-37.html
▼【PHP】連想配列、配列への追加
http://qiita.com/kazu56/items/6947a0e4830eb556d575

### 2-2-2. `[]`を用いた配列追加
```php
array_push($array1, $array2);
```

と

```php
$array1[] = $array2;
```

は同じ挙動をします。
なお、`array_push()`関数を用いるより`[]`を用いた方が若干速いらしいです。

# 3. おまけ
## 3-1. 配列の要素数確認
```php
count($array);
```

## 3-2. `foreach()`関数
配列を用いたループ計算は`foreach()`関数が便利です。

```php
$users[] = array('name'=>'tamura', 'age'=>'25');
$users[] = array('name'=>'suzuki', 'age'=>'23');
$users[] = array('name'=>'maki', 'age'=>'29');

foreach($users as $user)
  echo $user['name'] . 'さんは' . $user['age'] . "歳です。\n";
```

```
tamuraさんは25歳です。
suzukiさんは23歳です。
makiさんは29歳です。
```

## 3-3. 連想配列にキー追加
```php
$users[] = array('name'=>'tamura', 'age'=>'25');
$users[] = array('name'=>'suzuki', 'age'=>'23');
$users[] = array('name'=>'maki', 'age'=>'29');

print_r($users);

$users[0]['sex'] = 'male';
$users[1]['sex'] = 'female';
$users[2]['sex'] = 'male';

print_r($users);
```

```
Array
(
    [0] => Array
        (
            [name] => tamura
            [age] => 25
        )

    [1] => Array
        (
            [name] => suzuki
            [age] => 23
        )

    [2] => Array
        (
            [name] => maki
            [age] => 29
        )

)
Array
(
    [0] => Array
        (
            [name] => tamura
            [age] => 25
            [sex] => male
        )

    [1] => Array
        (
            [name] => suzuki
            [age] => 23
            [sex] => female
        )

    [2] => Array
        (
            [name] => maki
            [age] => 29
            [sex] => male
        )

)
```