.Dev.Record

#62334445b3361

【Laravel】へルパ関数の紹介 配列編1

2022.03.19

test

Laravelのへルパ関数超絶便利ですよね。筆者も開発時にはお世話になっています。

ただ、量が多くて全てを把握できていなかったので今回は配列関連のものに絞って調べてみました

参考になれば幸いです。

Memo

Laravelのバージョンは8系統になります。

配列関連のへルパ関数も量が多いので複数回に分けて紹介できればと思います。

今回解説するへルパ関数は以下です。

本記事で取り扱うへルパ関数

  • Arr::accessible(配列にアクセス可能かを判定)
  • Arr::add(配列に要素を追加)
  • Arr::collapse(配列を一次元配列に変換)
  • Arr::crossJoin(複数配列の直積集合を生成)
  • Arr::divide(配列をキーと要素で分割)
  • Arr::dot(配列をドット記法を使用して一次元配列に変換)
  • Arr::except(配列からキーを指定して要素を削除)
  • Arr::exists(配列内に指定したキーが存在するかを判定)

Arr::accessible 配列としてアクセス可能かを判定

引数に取った値が配列としてアクセス可能かを判定します。

accessible.php

1$array = ['hoge'];
2Arr::accessible($array); // 配列ならtrue
3
4$string = 'test';
5Arr::accessible($string); // 配列としてアクセスできないならfalse

ちなみにコレクションも配列としてアクセスできるのでtrueになります。

accessible.php

1$collection = Collection::make(['fuga']);
2Arr::accessible($collection); // true

Arr::add キーと値を配列に追加する

指定したkeyと値を配列の要素として追加します。

Arr::add

Arr::add(追加対象の配列(もしくはコレクション), 追加するキー, 追加する値)

add.php

1// 配列に追加
2$array = ['key1' => 'value1'];
3dd(Arr::add($array, 'key2', 'value2'));
4
5// 結果
6array:2 [7  "key1" => "value1"
8  "key2" => "value2"
9]
10
11// コレクションに追加
12$collection = Collection::make(['key1' => 'value1']);
13dd(Arr::add($collection, 'key2', 'value2'));
14
15// 結果
16Illuminate\Support\Collection {#306 ▼
17  #items: array:2 [▼
18    "key1" => "value1"
19    "key2" => "value2"
20  ]
21  #escapeWhenCastingToString: false
22}

追加する値は配列でも可能です。

add.php

1$array      = ['key1' => 'value1'];
2dd(Arr::add($array, 'key2', ['key3' => 'value2']));
3
4array:2 [5  "key1" => "value1"
6  "key2" => array:1 [7    "key3" => "value2"
8  ]
9]

追加しようとする:キーが既に存在していた場合nullの場合のみ値が上書きされます。

add.php

1$array      = ['key1' => null];
2dd(Arr::add($array, 'key1', 'added value1'));
3
4// 結果
5array:1 [6  "key1" => "added value1"
7]

ただし、値がnull以外の場合値は上書きされません

add.php

1$array = ['key1' => 'value1'];
2dd(Arr::add($array, 'key1', 'added value1'));
3
4// 結果
5array:1 [6  "key1" => "value1"
7]

ドット記法でキーの指定もできます。 ただし、下記の例のようにドットで指定した一階層上のキー(例ではkey1)が配列ではない場合は値が配列で上書きされてしまいます

add.php

1$array = ['key1' => 'value1'];
2dd(Arr::add($array, 'key1.key1-1', 'value1-1'));
3
4// 結果
5// key1のvalue1は上書きされてしまっている
6array:1 [7  "key1" => array:1 [8    "key1-1" => "value1-1"
9  ]
10]

Arr::collapse 多次元配列を一次元配列へ変換

指定した多次元配列を一次元配列に変換します。

Arr::collapse

Arr::collapse(多次元配列): array

  • コレクションを引数に取った場合でも返り値は配列
  • 配列の中に配列がある場合は一次元にしてくれない
  • キーが被っている場合は後方の値が優先

使用例

1$array = [
2    ['value1-1', 'value1-2'],
3    ['value2-1', 'value2-2'],
4];
5dd(Arr::collapse($array));
6
7// 結果
8array:4 [9  0 => "value1-1"
10  1 => "value1-2"
11  2 => "value2-1"
12  3 => "value2-2"
13]

コレクションを引数に取った場合は配列が返る

1// コレクションでも可能だが返り値は配列になる
2$collection = Collection::make([
3    ['value1-1', 'value1-2'],
4    ['value2-1', 'value2-2'],
5]);
6dd(Arr::collapse($collection));
7
8array:4 [9  0 => "value1-1"
10  1 => "value1-2"
11  2 => "value2-1"
12  3 => "value2-2"
13]

配列の中の配列は一次元にしてくれない

1// 配列の中に配列がある場合は、一次元配列に直してはくれない
2$array = [
3    ['value1-1', 'value1-2'],
4    ['value2-1', 'value2-2', ['value2-3-1', 'value2-3-2']], // 配列の中に配列
5];
6dd(Arr::collapse($array));
7
8// 結果
9array:5 [10  0 => "value1-1"
11  1 => "value1-2"
12  2 => "value2-1"
13  3 => "value2-2"
14  4 => array:2 [15    0 => "value2-3-1"
16    1 => "value2-3-2"
17  ]
18]

キーが被っている場合は後方の値が優先される

1// キーがかぶっている場合は後方の値が優先
2$array = [
3    ['key1' => 'value1-1', 'key2' => 'value1-2'],
4    ['key1' => 'value2-1', 'key2' => 'value2-2'],
5];
6dd(Arr::collapse($array));
7
8// 結果
9array:2 [10  "key1" => "value2-1"
11  "key2" => "value2-2"
12]

Arr::crossJoin 複数配列の直積集合を生成

複数配列内の要素の直積集合を生成します。

直積集合とは 複数の集合に対して、各集合から1つずつ要素を取り出して組みにしたものを要素として持つ、新たな集合のこと。

引用元: 直積集合とは - コトバンク

Arr::crossJoin

Arr::crossJoin(配列1, 配列2, 配列3, ...): array

  • 引数に取るのは配列以外でもIteratableなものであればいいのでコレクションも可
  • 連想配列の場合はキーは無視されて、添字配列として返ってくる
  • 多次元配列の場合は、多次元配列部分は1要素として直積集合が生成される

これ自前で実装しようとするとかなり見にくいコードになりそうなので、へルパ関数で提供されているのはありがたいですね。

使用例

1dd(Arr::crossJoin([1, 2], [3, 4, 5]));
2
3// 結果
4array:6 [5  0 => array:2 [6    0 => 1
7    1 => 3
8  ]
9  1 => array:2 [10    0 => 1
11    1 => 4
12  ]
13  2 => array:2 [14    0 => 1
15    1 => 5
16  ]
17  3 => array:2 [18    0 => 2
19    1 => 3
20  ]
21  4 => array:2 [22    0 => 2
23    1 => 4
24  ]
25  5 => array:2 [26    0 => 2
27    1 => 5
28  ]
29]

コレクションでの使用例

1dd(Arr::crossJoin([1, 2], Collection::make([3, 4, 5])));
2
3// 結果
4array:6 [5  0 => array:2 [6    0 => 1
7    1 => 3
8  ]
9  1 => array:2 [10    0 => 1
11    1 => 4
12  ]
13  2 => array:2 [14    0 => 1
15    1 => 5
16  ]
17  3 => array:2 [18    0 => 2
19    1 => 3
20  ]
21  4 => array:2 [22    0 => 2
23    1 => 4
24  ]
25  5 => array:2 [26    0 => 2
27    1 => 5
28  ]
29]

連想配列で使用した場合

1$array1 = ['key1' => 1, 'key2' => 2];
2$array2 = ['key3' => 3, 'key4' => 4];
3
4dd(Arr::crossJoin($array1, $array2));
5
6// 結果(キーは除外される)
7array:4 [8  0 => array:2 [9    0 => 1
10    1 => 3
11  ]
12  1 => array:2 [13    0 => 1
14    1 => 4
15  ]
16  2 => array:2 [17    0 => 2
18    1 => 3
19  ]
20  3 => array:2 [21    0 => 2
22    1 => 4
23  ]
24]

多次元配列を用いた場合

1$array1 = [1, [2, 3]];
2$array2 = [4, [5, 6, 7]];
3dd(Arr::crossJoin($array1, $array2));
4
5// 結果(多次元配列部分が1要素として直積集合が形成される)
6array:4 [7  0 => array:2 [8    0 => 1
9    1 => 4
10  ]
11  1 => array:2 [12    0 => 1
13    1 => array:3 [14      0 => 5
15      1 => 6
16      2 => 7
17    ]
18  ]
19  2 => array:2 [20    0 => array:2 [21      0 => 2
22      1 => 3
23    ]
24    1 => 4
25  ]
26  3 => array:2 [27    0 => array:2 [28      0 => 2
29      1 => 3
30    ]
31    1 => array:3 [32      0 => 5
33      1 => 6
34      2 => 7
35    ]
36  ]
37]

Arr::divide 配列のキーと値を分ける

指定した配列のキーと値をそれぞれ別の変数に格納します

Arr::divide

Arr::divide(配列): [キーの配列, 値の配列]

  • 多次元配列を使用した場合は多次元配列部分は1つの値として扱われる
  • 純粋な配列しか扱えないのでコレクションを使用するとエラーになる

使用例

1dd(Arr::divide(['key1' => 1, 'key2' => 2, 'key3' => 2]));
2
3// 結果
4array:2 [5  0 => array:3 [// キー
6    0 => "key1"
7    1 => "key2"
8    2 => "key3"
9  ]
10  1 => array:3 [// 値
11    0 => 1
12    1 => 2
13    2 => 2
14  ]
15]

多次元配列を使用した場合

1dd(Arr::divide([1, [2, 3], 4]));
2
3// 結果
4array:2 [5  0 => array:3 [6    0 => 0
7    1 => 1
8    2 => 2
9  ]
10  1 => array:3 [11    0 => 1
12    1 => array:2 [// 多次元配列部分は一つの要素として扱われる
13      0 => 2
14      1 => 3
15    ]
16    2 => 4
17  ]
18]

コレクションを使用するとエラーになる

1dd(Arr::divide(Collection::make([1, 2, 3])));
2
3// 結果(エラー)
4// array_keys(): Argument #1 ($array) must be of type array, Illuminate\Support\Collection given

Arr::dot 多次元配列をドット記法で表した一次元配列に変換

多次元配列をドット記法で表した一次元配列に変換します。

Arr:dot

Arr::dot(多次元配列, キーのプレフィックス文字列(デフォルトは空文字)): array

  • コレクションも可(返り値は配列)
  • 添字配列が含まれている場合は、数字で表現される
  • 第二引数にキーに使用するプレフィックスを指定できる(デフォルトは空文字)

使用例(配列)

1$array = [
2    'key1' => ['key1-1' => 1, 'key1-2' => 2],
3    'key2' => ['key2-1' => ['key-2-1-1' => 3], ],
4];
5dd(Arr::dot($array));
6
7// 結果
8array:3 [9  "key1.key1-1" => 1
10  "key1.key1-2" => 2
11  "key2.key2-1.key-2-1-1" => 3
12]

使用例(コレクション)

1$collection = Collection::make([
2    'key1' => ['key1-1' => 1, 'key1-2' => 2],
3    'key2' => ['key2-1' => ['key-2-1-1' => 3], ],
4]);
5dd(Arr::dot($array));
6
7// 結果
8array:3 [9  "key1.key1-1" => 1
10  "key1.key1-2" => 2
11  "key2.key2-1.key-2-1-1" => 3
12]

添字配列が含まれている場合

1$array = [
2    ['key1-1' => 1, 'key1-2' => 2],
3    ['key2-1' => ['key-2-1-1' => 3], ],
4];
5dd(Arr::dot($array));
6
7// 結果(添字配列部分は数字で表現される)
8array:3 [9  "0.key1-1" => 1
10  "0.key1-2" => 2
11  "1.key2-1.key-2-1-1" => 3
12]

第二引数にプレフィックスを使用

1$array = [
2    'key1' => ['key1-1' => 1, 'key1-2' => 2],
3    'key2' => ['key2-1' => ['key-2-1-1' => 3], ],
4];
5dd(Arr::dot($array, 'key-prefix-'));
6
7// 結果(キーの前に第二引数で指定したkey-prefix-が付与される)
8array:3 [9  "key-prefix-key1.key1-1" => 1
10  "key-prefix-key1.key1-2" => 2
11  "key-prefix-key2.key2-1.key-2-1-1" => 3
12]

Arr::except 配列から指定したキーと対応する要素を削除する

配列から指定したキーと対応する要素を削除します。

Arr:except

Arr::except(配列, 削除するキー): array

  • コレクションも可(削除後のコレクションが返ってくる)
  • 削除後に要素がなくなった場合は空の配列が返ってくる
  • 削除するキーは配列で複数指定も可能
  • 削除するキーが存在しない場合は配列の要素に変化なし

使用例

1$array = [
2    'key1' => 1,
3    'key2' => 2,
4];
5dd(Arr::except($array, 'key1'));
6
7// 結果(指定したキーの要素が削除される)
8array:1 [9  "key2" => 2
10]

コレクションを使用した場合

1$collection = Collection::make([
2    'key1' => 1,
3    'key2' => 2,
4]);
5dd(Arr::except($collection, 'key1'));
6
7// 結果
8Illuminate\Support\Collection {#306 ▼
9  items: array:1 [10    "key2" => 2
11  ]
12  escapeWhenCastingToString: false
13}

削除するキー配列で複数指定

1$array = [
2    'key1' => 1,
3    'key2' => 2,
4    'key3' => 3,
5];
6dd(Arr::except($array, ['key1', 'key2']));
7
8// 結果
9array:1 [10  "key3" => 3
11]

Arr::exists 指定したキーが配列に含まれているかを判定

指定したキーが配列に含まれている場合にtrueを返します。

Arr:exists

Arr::exists(配列, 調べるキー): bool

  • 配列が添字配列の場合は、調べるキーに添字を指定する
  • コレクションも可
  • 多次元配列の場合は多次元部分のキーは調べられない
  • コレクションは調べるキーを配列で複数指定可能(完全一致)だが、配列の場合は不可

使用例

1$array = [
2    'key1' => 1,
3    'key2' => 2,
4];
5// true
6Arr::exists($array, 'key1');
7
8// false
9Arr::exists($array, 'key3');

添字配列の場合

1$array = [1, 2,];
2
3// true
4Arr::exists($array, 0);
5
6// false
7Arr::exists($array, 2);

コレクションの場合

1$collection = Collection::make(['key-1' => 1, 'key-2' => 2,]);
2// true
3Arr::exists($collection, 'key-1');
4
5$collection = Collection::make([1, 2,]);
6// false
7Arr::exists($collection, 2);

多次元配列の場合

1$array = ['key-1' => 1, ['key-2' => 2]];
2
3// 多次元部分のキーは調べられない
4// false
5Arr::exists($array, 'key-2');
6
7// 一階層目のキーは調べられる
8// true
9Arr::exists($array, 'key-1');

コレクションのみ、調べるキーを複数指定が可能です。

コレクションの場合のみ調べるキーが複数指定可能

1$collection = Collection::make(['key-1' => 1, 'key-2' => 2]);
2
3// true
4Arr::exists($collection, ['key-1', 'key-2']);
5
6// false
7Arr::exists($collection, ['key-1', 'key-3']);

配列の場合はエラーになります。

配列の場合はエラー

1$array = ['key-1' => 1, 'key-2' => 2];
2Arr::exists(['key-1', 'key-2']);
3
4// エラーになる
5// array_key_exists(): Argument #1 ($key) must be a valid array offset type

複数のキーを指定した場合について

Arr::existsの実装部分が以下のコードになります。

existsの実装コード

1/**
2* Determine if the given key exists in the provided array.
3*
4* @param  \ArrayAccess|array  $array
5* @param  string|int  $key
6* @return bool
7*/
8public static function exists($array, $key)
9{
10    if ($array instanceof Enumerable) {
11        return $array->has($key);
12    }
13
14    if ($array instanceof ArrayAccess) {
15        return $array->offsetExists($key);
16    }
17
18    return array_key_exists($key, $array);
19}

コレクションでは複数キーで検索できるのに対して配列の場合はエラーになってしまう現象ですが、 PHPDocを見ると第二引数の$keystring|intの型で明記されているので複数キーを指定されることが想定されていないかもしれません。

以上今回は、8つの配列関連のへルパ関数の解説でした。

残りは別記事で解説予定です。

.Dev.Record