.Dev.Record

#623d3e1aa7bb3

【Laravel】ヘルパ関数の紹介 配列編5【random、set、shuffle、sort、sortRecursive】

2022.03.25

test

前回に引き続き本記事でもLaravelの配列関連のへルパ関数を解説していきたいと思います。

参考になれば幸いです。

Memo

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

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

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

  • Arr::random 配列からランダムに値を返す
  • Arr::set ドット記法を使用して配列に要素を追加
  • Arr::shuffle 配列内の要素をランダムに入れ替える
  • Arr::sort 配列の値に基づき要素を昇順ソートする
  • Arr::sortRecursive 連想配列の場合はキーを添字配列の場合は値を基準にソートする

Arr::random 配列からランダムに値を返す

配列からランダムに値を返します

Arr::random

Arr::random(配列, (オプション)取得する個数, (オプション)キーを含めるか)

  • 第二引数にはランダムに返す個数を指定できる
  • 第三引数には取得元が連想配列の場合に返す値にキーを含めるか指定できる
  • コレクションは使用不可(エラー)

使用例

1$array = [1, 2, 3, 4];
2dd(Arr::random($array));
3// 結果(ランダムに値を返す)
42
5
6dd(Arr::random($array));
7// 結果(ランダムに値を返す)
81

第二引数でランダムに返す個数を指定できます。

第二引数を指定

1$array = [1, 2, 3, 4];
2// 第二引数にランダムに返す個数を指定
3dd(Arr::random($array, 3));
4
5// 結果(3つの値がランダムに返される)
6array:3 [7  0 => 1
8  1 => 3
9  2 => 4
10]

注意

第二引数に1を明示的に指定した場合と第二引数に何も指定しない場合で微妙に挙動が変わります。

返される値の個数は共に1つですが下記の違いがあります。

  • 第二引数に1を明示的に指定した場合は配列で返される
  • 第二引数に何も指定しない場合は値そのものが返される

1$array = [1, 2, 3, 4];
2
3// 第二引数に1を指定した場合は配列で返される
4dd(Arr::random($array, 1));
5// 結果
6array:3 [7  0 => 1
8]
9
10// 第二引数に何も指定しない場合は値そのものが返される
11dd(Arr::random($array));
12// 結果
131

第三引数をtrueにすると連想配列の場合返却される値にキーも反映されるようになります。

第三引数を指定

1$array = ['key-1' => 1, 'key-2' => 2, 'key-3' => 3];
2// 第三引数をtrueにして返り値にキーを反映するよう指定
3dd(Arr::random($array, 1, true));
4
5// 結果(取得元の配列キーが反映されている)
6array:1 [7  "key-2" => 2
8]
9
10// デフォルトはfalseが指定されている
11$array = ['key-1' => 1, 'key-2' => 2, 'key-3' => 3];
12dd(Arr::random($array, 1));
13
14// 結果(取得元のキーは反映されず添字配列として返却される)
15array:1 [16  0 => 1
17]

コレクションは使用できません。(エラーになります。)

コレクション(エラー)

1$collection = Collection::make([1, 2, 3]);
2dd(Arr::random($collection));
3
4// エラー
5// array_rand(): Argument #1 ($array) must be of type array, Illuminate\Support\Collection given

Arr::set ドット記法を使用して配列に要素を追加

ドット記法を使用して配列に要素を追加できます。

Arr::set

Arr::set(&配列, 追加するキー, 追加する値): array

  • ドット記法で追加するキーを指定できる
  • 第一引数に渡す配列は参照渡しで副作用が生じる
  • コレクションは使用不可(エラー)

使用例

1$array = ['key-1' => 1, 'key-2' => ['key-2-1' => 2]];
2Arr::set($array, 'key-2.key-2-2', 3);
3dd($array);
4
5// 結果(ドット記法で指定したキーと値が追加されている)
6array:2 [7  "key-1" => 1
8  "key-2" => array:2 [9    "key-2-1" => 2
10    "key-2-2" => 3
11  ]
12]
13
14// 返り値には追加した階層部分の配列が返される
15array:2 [16  "key-2-1" => 2
17  "key-2-2" => 3
18]

Memo

引数に渡した配列は参照渡しです。

Arr::set後は引数に渡した配列自体の中身が変化する副作用が生じます。

コレクションは使用不可で、エラーになります。

コレクション(エラー)

1$collection = Collection::make(['key-1' => 1, 'key-2' => ['key-2-1' => 2]]);
2Arr::set($collection, 'key-2.key-2-2', 3);
3
4// エラー
5// Indirect modification of overloaded element of Illuminate\Support\Collection has no effect

Arr::shuffle 配列内の要素をランダムに入れ替える

配列内の要素をランダムに入れ替えます

Arr::shuffle

Arr::shuffle(配列, (オプション)シード値)

  • 第二引数にはシード値を指定できる。(要素内の入れ替え方を決める値なのでシード値を指定すると毎回同じ実行結果が返ってくる)
  • コレクションは使用不可(エラー)

使用例

1$array = [1, 2, 3, 4];
2dd(Arr::shuffle($array));
3
4// 結果(配列内の要素がランダムに入れ替わる)
5// 1回目
6array:4 [7  0 => 4
8  1 => 1
9  2 => 2
10  3 => 3
11]
12
13// 2回目(ランダムに入れ替わるので1回目と異なる並び順になる)
14array:4 [15  0 => 2
16  1 => 3
17  2 => 4
18  3 => 1
19]

第二引数にはシード値を設定できます。

シード値について調べてみたのですがよくわかりませんでした。

乱数生成器を初期化する値のようで、設定すると毎回同じ乱数を生成するので何度実行しても同じ結果が返ってくるようになります。(この理解であっているかはかなり怪しいです)

実行毎に入れ替え方をランダムに変化させたい場合は設定しないようにします。

第二引数を指定

1$array = [1, 2, 3, 4];
2dd(Arr::shuffle($array, 1));
3
4// 結果(何回実行しても入れ替え方が同じ)
5// 1回目
6array:4 [7  0 => 4
8  1 => 1
9  2 => 3
10  3 => 2
11]
12
13// 2回目
14array:4 [15  0 => 4
16  1 => 1
17  2 => 3
18  3 => 2
19]
20
21// 3回目
22array:4 [23  0 => 4
24  1 => 1
25  2 => 3
26  3 => 2
27]

コレクションは使用不可でエラーになります。

コレクション(エラー)

1$collection = Collection::make([1, 2, 3, 4]);
2Arr::shuffle($collection);
3
4// エラー
5// shuffle(): Argument #1 ($array) must be of type array, Illuminate\Support\Collection given

Arr::sort 配列の値に基づき要素を昇順ソートする

配列内の値をソートします。

使用例

1$array = ['PHP', 'Laravel', 'HTML', 'CSS'];
2dd(Arr::sort($array));
3
4// 結果(昇順でソートされている)
5array:4 [6  3 => "CSS"
7  2 => "HTML"
8  1 => "Laravel"
9  0 => "PHP"
10]

例をみるとわかるように、添字配列のキーはリセットされません

第二引数にコールバック関数を使用してソートさせたいキーを指定できます

ソートするキーを指定

1$array = [
2    ['id' => 4, 'name' => 'PHP'],
3    ['id' => 1, 'name' => 'Laravel'],
4    ['id' => 3, 'name' => 'HTML'],
5    ['id' => 2, 'name' => 'CSS'],
6];
7
8// コールバック関数内でidでソートするように指定
9dd(Arr::sort($array, function($value) {
10    return $value['id'];
11}));
12
13// 結果(idの昇順でソートされている)
14array:4 [15  1 => array:2 [16    "id" => 1
17    "name" => "Laravel"
18  ]
19  3 => array:2 [20    "id" => 2
21    "name" => "CSS"
22  ]
23  2 => array:2 [24    "id" => 3
25    "name" => "HTML"
26  ]
27  0 => array:2 [28    "id" => 4
29    "name" => "PHP"
30  ]
31]
32
33$array = [
34    ['id' => 4, 'name' => 'PHP'],
35    ['id' => 1, 'name' => 'Laravel'],
36    ['id' => 3, 'name' => 'HTML'],
37    ['id' => 2, 'name' => 'CSS'],
38];
39
40// コールバック関数内でnameでソートするように指定
41dd(Arr::sort($array, function($value) {
42    return $value['name'];
43}));
44
45// 結果(nameの昇順でソートされている)
46array:4 [47  3 => array:2 [48    "id" => 2
49    "name" => "CSS"
50  ]
51  2 => array:2 [52    "id" => 3
53    "name" => "HTML"
54  ]
55  1 => array:2 [56    "id" => 1
57    "name" => "Laravel"
58  ]
59  0 => array:2 [60    "id" => 4
61    "name" => "PHP"
62  ]
63]

コレクションでも使用できます。

コレクション

1$collection = Collection::make([
2    ['id' => 4, 'name' => 'PHP'],
3    ['id' => 1, 'name' => 'Laravel'],
4    ['id' => 3, 'name' => 'HTML'],
5    ['id' => 2, 'name' => 'CSS'],
6]);
7dd(Arr::sort($collection, function($value) {
8    return $value['name'];
9}));
10
11// 結果
12array:4 [13  3 => array:2 [14    "id" => 2
15    "name" => "CSS"
16  ]
17  2 => array:2 [18    "id" => 3
19    "name" => "HTML"
20  ]
21  1 => array:2 [22    "id" => 1
23    "name" => "Laravel"
24  ]
25  0 => array:2 [26    "id" => 4
27    "name" => "PHP"
28  ]
29]
30});

Arr::sortRecursive 連想配列の場合はキーを添字配列の場合は値を基準にソートする

配列内の要素を連想配列の場合はキーを添字配列の場合は値を基準にソートします。

Arr::sortRecursive

Arr::sortRecursive(配列, (オプション)ソート方法, (オプション)並び順)

  • 配列は多次元配列でも可能
  • 第二引数にはソート方法が指定可能
  • 第三引数には並び順を指定可能(trueは降順でfalseが昇順。デフォルトは昇順
  • コレクションは使用不可(エラー)

使用例

1// 添字配列の場合は値の昇順でソート
2$array = [5, 4, 3, 2, 1];
3dd(Arr::sortRecursive($array));
4
5// 結果(昇順でソートされている)
6array:5 [7  0 => 1
8  1 => 2
9  2 => 3
10  3 => 4
11  4 => 5
12]
13
14// 連想配列の場合はキーを基準にソート
15$array = ['key-3' => 1, 'key-2' => 2, 'key-1' => 3];
16dd(Arr::sortRecursive($array));
17
18// 結果(キーの昇順でソートされている)
19array:3 [20  "key-1" => 3
21  "key-2" => 2
22  "key-3" => 1
23]

多次元配列の場合でも使用できます。

多次元配列

1$array = [
2    ['key-3' => 1, 'key-2' => 2, 'key-1' => 3],
3    [5, 4, 3, 2, ['key-2' => 1, 'key-1' => 2]],
4];
5dd(Arr::sortRecursive($array));
6
7// 結果
8array:2 [9  0 => array:3 [10    "key-1" => 3
11    "key-2" => 2
12    "key-3" => 1
13  ]
14  1 => array:5 [15    0 => 2
16    1 => 3
17    2 => 4
18    3 => 5
19    4 => array:2 [20      "key-1" => 2
21      "key-2" => 1
22    ]
23  ]
24]

第二引数では比較方法を指定できます。

第二引数に比較方法を指定

1$array = [1, 2, 3, 111];
2// 第二引数の比較方法に文字列比較を指定する`SORT_STRING`を設定
3dd(Arr::sortRecursive($array, SORT_STRING));
4
5// 結果(文字列として比較しているので2番目に111がきている)
6array:4 [7  0 => 1
8  1 => 111
9  2 => 2
10  3 => 3
11]

第二引数に指定できるのは、PHPの組込み関数sortに指定できるものと同じで下記になります。

(デフォルトではSORT_REGULARが設定されています。)

第二引数に指定できる値

  • SORT_REGULAR : 通常通りに項目を比較します。
  • SORT_NUMERIC : 数値として項目を比較します。
  • SORT_STRING : 文字列として項目を比較します。
  • SORT_LOCALE_STRING : 現在のロケールに基づいて、文字列として項目を比較します。 比較に使うロケールは、setlocale() 関数で変更できます。
  • SORT_NATURAL : 要素の比較を文字列として行い、 natsort() と同様の「自然順」で比較します。
  • SORT_FLAG_CASE : SORT_STRING や SORT_NATURAL と (ビットORで) 組み合わせて使い、 文字列のソートで大文字小文字を区別しないようにします。

引用元:PHP: rsort - Manual

一点注意事項として、第二引数にSORT_STRINGSORT_LOCALE_STRINGSORT_NATURALを使用して多次元配列のソートをかけようとするとエラーになります。

これは文字列比較する際に多次元部分の配列を文字列に変換しようとして起こるエラーのようです。

多次元配列で第二引数に文字列比較を設定(エラー)

1$array = [1, 2, 3, [111]];
2Arr::sortRecursive($array, SORT_LOCALE_STRING);
3
4// エラー
5// Array to string conversion

注意

  • 多次元配列のソート時に第二引数にSORT_STRINGSORT_LOCALE_STRINGSORT_NATURALを指定するとエラーになる

第三引数には並び順を昇順か降順かを指定できます。

第三引数にtrueを指定すると降順falseを指定すると昇順になります。(デフォルトは昇順)

第三引数に並び順を指定

1$array = [1, 2, 3, 111];
2// 並び順を降順にするため第三引数にtrueを指定
3dd(Arr::sortRecursive($array, SORT_STRING, true));
4
5// 結果(降順に並ぶ)
6array:4 [7  0 => 3
8  1 => 2
9  2 => 111
10  3 => 1
11]

コレクションは使用不可です。(エラーになります。)

コレクション

1$collection = Collection::make([1, 2, 3, 111]);
2Arr::sortRecursive($collection, SORT_STRING);
3
4// エラー
5// Illuminate\Support\Arr::isAssoc(): Argument #1 ($array) must be of type array, Illuminate\Support\Collection given, called in /var/www/html/vendor/laravel/framework/src/Illuminate/Collections/Arr.php on line 672

.Dev.Record