【PHP】連想配列の作成と要素の変更、追加方法まとめ。キーや値を変更・追加の実例。

PHPにおける連想配列の操作方法について。

PHPでは連想配列は、配列の各値にキー名が設定してあるものを指す。


##目次

1. [連想配列の作成方法](#連想配列の作成方法)
2. [値の変更と追加まとめ](#値の変更と追加まとめ)
3. [値の変更](#値の変更)
4. [値の追加](#値の追加)
    5. [キー名を指定する](#1-キー名を指定する)
    6. [+演算子を使う](#2-演算子を使う)
    7. [array_merge関数を使う](#3-array_merge関数を使う)
8. [キーの変更](#キーの変更)
9. [キー全体を変更する場合](#キー全体を変更する場合)
    10. [foreachを使う](#foreachを使う)
    11. [array_combine関数を使う](#array_combine関数を使う)
12. [一部のキーだけを変更する方法](#一部のキーだけを変更する方法)
    13. [foreach文とif文を使う](#foreach文とif文を使う)
    14. [array_combainとarray_keysを使う](#array_combainとarray_keysを使う)


<br>
##連想配列の作成方法
連想配列は配列の一種なので`array関数`または`[ ]`を使う。KV（key-value）の指定は、`キー名 => 値`で行う。

「=>」をダブルアロー演算子と呼ぶ。

>※キー名が文字列の場合は、`'`、`"`で囲む。整数の場合は不要。
※ダブルアロー「=>」を使う。アロー「->」は別の用途で使用される（インスタンスのプロパティやメソッドの指定）

```php:array関数
$obj = array('a' => 1, 'b' => 2, 999 => 3);

var_export($obj);
array (
  'a' => 1,
  'b' => 2,
  999 => 3,
)
```

```php:カッコを使う
$obj2 = ['a' => 1, 'b' => 2, 999 => 3];

var_export($obj2);
array (
  'a' => 1,
  'b' => 2,
  999 => 3,
)
```

カッコを使った方が簡単。


<br>
####▼キー名に整数以外を使う場合は文字列にしないとエラーになる

```php:
$x = array(a => 1);

#PHP Warning:  Use of undefined constant a - assumed 'a' (this will throw an Error in a future version of PHP) in php shell code on line 1
```

>PHP Warning:  Use of undefined constant a - assumed 'a' (this will throw an Error in a future version of PHP) in php shell code on line 1

aはダメ。'a'にしてとのメッセージ。



<br>
##値の変更と追加まとめ
破壊を気にしなければ`$変数[キー名] = 値`が最も使いやすい。

非破壊で行いたい場合は`array_merge()`が使いやすい。


| 項目 | $変数[キー名] = 値 | +演算子 | array_merge関数 |
|:-:|:-:|:-:|:-:|
| 破壊/非破壊  | 破壊  | 非破壊  | 非破壊  |
| KVの追加  | 可  | 可  | 可  |
| 値の変更  | 可  |  不可 | 可  |
| 整数のキーが通常の配列に変換  | 無し  |  無し | 変換  |


<br>
##値の変更
キー名を指定して新しい値を代入する。

`$変数名[キー名] = 変更後の値`


```php:
$obj = array('a' => 1, 'b' => 2, 999 => 3);

#値の変更
$obj['b'] = 1000;

#変数の内容表示
var_export($obj);
array (
  'a' => 1,
  'b' => 1000,
  999 => 3,
)
```



<br>
##値の追加
値を追加する方法はいくつかある。いずれの方法でも新たに追加した要素は一番後ろに入る。



###1. キー名を指定する
先ほどの値を変更する方法で、存在しないキーを指定すると新たに
そのキーと値が追加される。

`$変数名[追加するキー名] = 変更後の値`

```php:
$obj = array('a' => 1, 'b' => 2, 999 => 3);

#キーと値の追加
$obj['c'] = 3;

var_export($obj);
array (
  'a' => 1,
  'b' => 2,
  999 => 3,
  'c' => 3,
)
```

<br>
###2. +演算子を使う
連想配列に対して+演算子を使うことで、新たなKVのセットを追加することができる。

>※+演算子の場合、既存の値変更はできない。

```php:
$obj = array('a' => 1, 'b' => 2, 999 => 3);

#新たなキーと値を追加
$obj = $obj + array('c' => 3);

var_export($obj);
array (
  'a' => 1,
  'b' => 2,
  999 => 3,
  'c' => 3,
)
```

<br>
**▼複数のKVを追加することも可能**

```php:
$obj = array('a' => 1, 'b' => 2, 999 => 3);

#3つの要素を追加
$obj += array('c' => 3, 'str', 1000);

var_export($obj);
array (
  'a' => 1,
  'b' => 2,
  999 => 3,
  'c' => 3,
  0 => 'str',
  1 => 1000,
)

```

キーを指定せずに値を追加した場合は、**0から順に整数でキーが割り振られる**。

これは、連想配列でない通常の配列要素になったことを示す。

```php:（参考）通常の配列
$arr = [1,2,3];
var_export($arr);
array (
  0 => 1,
  1 => 2,
  2 => 3,
)
```



<br>
**▼既存のキーの値を変更はできない**

```php:既存のキーの値を変更はできない
$obj = array('a' => 1, 'b' => 2, 999 => 3);
$obj = $obj + array('b' => 1);
php > var_export($obj);
array (
  'a' => 1,
  'b' => 2,
  999 => 3,
)
```



<br>
###3. array_merge関数を使う

`array_merge(配列, 配列,,,,,)`

>※数値や文字列は指定できない。（指定するとエラーになる）
※キーが数値の場合、0から順の数値に変換される。
※キーが重複する場合は後ろの配列の値が適用される（上書きされる）


```php:
$obj = array('a' => 1, 'b' => 2, 999 => 3);
$x = array('x' => 1);

#配列を足し合わせる
$obj = array_merge($obj, $x);
var_export($obj);
array (
  'a' => 1,
  'b' => 2,
  0 => 3,
  'x' => 1,
)
```

`$obj`に$xが追加された。

>※キーが数値の場合、0から順の数値に変換される。


<br>
**▼配列が複数の場合**

```php:
$obj = array('a' => 1, 'b' => 2, 999 => 3);
$x = array('x' => 1);
$arr = [1,2,3];

#配列を足し合わせる
$obj = array_merge($obj, $x, array('c'=>4), $arr);

var_export($obj);
array (
  'a' => 1,
  'b' => 2,
  0 => 3,
  'x' => 1,
  'c' => 4,
  1 => 1,
  2 => 2,
  3 => 3,
)
```


<br>
**▼キーが重複する場合**

```php:
$obj = array('a' => 1, 'b' => 2, 999 => 3);
$obj2 = array('a' => 9, 'b' => 8, 999 => 7);

$obj = array_merge($obj, $obj2);

var_export($obj);
array (
  'a' => 9,
  'b' => 8,
  0 => 3,
  1 => 7,
)
```

キーが数値の場合は0からの連番に自動変更されるので、重複とみなされない。



<br>
##キーの変更
値を変更したようにキーを指定して置き換える直接的な方法はない。

新しいキーをもつ配列を用意するか、元のキーを削除して新たにキーを作成し値を代入する方法が考えられる。


###キー全体を変更する場合

###foreachを使う
foreach文で値を一つづつ取り出し、新しいキーにセットしていく。

**▼foreach文**
変数の指定方法により、値のみ抜き出すか、キーと値の両方を抜き出すかが変わる。

・`foreach( 配列 as 変数 ){処理}`
配列が連想配列の場合、変数には各要素の値（value）が入る

・`foreach( 配列 as 変数1 => 変数2 ){処理}`
配列が連想配列の場合、変数１にはキー名(key)、変数２には値（value）が入る。


```php:
$obj = array('a' => 1, 'b' => 2, 999 => 3);

#新たなキー名を入れる連想配列
$newObj = [];

#キー名の識別用
$i = 0;

foreach ($obj as $v){
  $newObj["key_$i"] = $v;
  $i += 1;
}

#中身確認
var_export($newObj);
array (
  'key_0' => 1,
  'key_1' => 2,
  'key_2' => 3,
)
```



<br>
####新しい連想配列のキー名に古いキー名を活用する場合
`foreach( 配列 as 変数1 => 変数2 ){処理}`の変数１にキー名が入るため、これを新たなキー名として活用する。


```php:事例1（番号をふる）
$obj = array('a' => 1, 'b' => 2, 999 => 3);

#新たなキー名を入れる連想配列
$newObj = [];

$i = 0;
foreach ($obj as $k => $v){
  $newObj[$k."_".$i] = $v;
  $i += 1;
}

#中身確認
var_export($newObj);
array (
  'a_0' => 1,
  'b_1' => 2,
  '999_2' => 3,
)
```


```php:事例2（文字列をくっつける）
$obj = array('a' => 1, 'b' => 2, 999 => 3);

#新たなキー名を入れる連想配列
$newObj = [];

foreach ($obj as $k => $v){
  $newObj["new_$k"] = $v;
}

#中身確認
var_export($newObj);
array (
  'new_a' => 1,
  'new_b' => 2,
  'new_999' => 3,
)
```


<br>
元の変数をそのまま利用したい場合は、新たに作成した変数を代入すればいい。

```php:
$obj = $newObj;
php > var_export($obj);
array (
  'new_a' => 1,
  'new_b' => 2,
  'new_999' => 3,
)
```

```php:不要になった配列の削除
unset($newObj);

var_export($newObj);
#PHP Notice:  Undefined variable: newObj in php shell code on line 1
#NULL
```

`unset(変数)`は指定した変数を削除する関数。


<br>
##array_combine関数を使う
・`array_combine ( array $keys , array $values )`
第1引数の配列の要素をキーとして、第２引数の配列の要素を値として、連想配列を生成する関数。

第２引数の配列は`array_values()`で値のみを抜き出した配列を使用する。

```php:
$obj = ['a' => 1, 'b' => 2, 999 => 3];

#keyとvalueの配列を作成
$keys = ['x', 'y', 'z'];
$vals = array_values($obj);

#結合
$res = array_combine($keys, $vals);

#確認
var_export($res);
array (
  'x' => 1,
  'y' => 2,
  'z' => 3,
)
```


<br>
####▼要素数が合わない場合はエラーになる

```php:
$obj = ['a' => 1, 'b' => 2, 999 => 3];

#keyは２つ
$keys = ['x', 'y'];

#valueは３つ
$vals = array_values($obj);

#結合
$res = array_combine($keys, $vals);
PHP Warning:  array_combine(): Both parameters should have an equal number of elements in php shell code on line 1
```

>PHP Warning:  array_combine(): Both parameters should have an equal number of elements in php shell code on line 1



<br>
##一部のキーだけを変更する方法

###foreach文とif文を使う
if文で指定したキーのみ値を変更する。

```php:
$obj = ['a' => 1, 'b' => 2, 999 => 3];

#新たなキー名を入れる連想配列
$newObj = [];

foreach ($obj as $k => $v){
  #変更するキーを指定
  if( $k == '999' ){
    $newObj['c'] = $v;
  }
  #それ以外のキーと値はそのまま
  else {
    $newObj[$k] = $v;
  }
}

#中身確認
var_export($newObj);
array (
  'a' => 1,
  'b' => 2,
  'c' => 3,
)
```


<br>
###array_combainとarray_keysを使う
・`array_combine ( array $keys , array $values )`
第1引数の配列の要素をキーとして、第２引数の配列の要素を値として、連想配列を生成する関数。

第１引数の配列は`array_keys()`でキーのみを抜き出した配列を作成し、指定した要素の値を変更する。

第２引数の配列は`array_values()`で値のみを抜き出した配列を使用する。


```php:
$obj = ['a' => 1, 'b' => 2, 999 => 3];

#キーの抽出
$keys = array_keys($obj);
#指定した値の変更
$keys[2] = 'c';

#値の抽出
$vals = array_values($obj);

#結合
$newObj = array_combine($keys, $vals);

#中身確認
var_export($newObj);
array (
  'a' => 1,
  'b' => 2,
  'c' => 3,
)
```