概要
Laravel
のCollection
には、count()
やsum()
などの集計用メソッドが準備されている。groupBy()
メソッドも準備されているが、これはグルーピングされたキー列の値で配列をまとめるだけなので、直接groupBy()
の結果をcount()
などに適用することはできない。
たとえば以下のようなコレクションがあって、
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
>>> $p => Illuminate\Support\Collection {#4355 all: [ [ "name" => "Egawa", "gender" => "male", "height" => 175, ], [ "name" => "Iwata", "gender" => "female", "height" => 163, ], [ "name" => "Okada", "gender" => "male", "height" => 168, ], [ "name" => "Ando", "gender" => "male", "height" => 182, ], [ "name" => "Ueda", "gender" => "female", "height" => 167, ], ], } |
groupBy()
によってgender
でグルーピングすると以下のようなコレクションが得られる。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
>>> $p->groupBy('gender') => Illuminate\Support\Collection {#4341 all: [ "male" => Illuminate\Support\Collection {#4367 all: [ [ "name" => "Egawa", "gender" => "male", "height" => 175, ], [ "name" => "Okada", "gender" => "male", "height" => 168, ], [ "name" => "Ando", "gender" => "male", "height" => 182, ], ], }, "female" => Illuminate\Support\Collection {#4360 all: [ [ "name" => "Iwata", "gender" => "female", "height" => 163, ], [ "name" => "Ueda", "gender" => "female", "height" => 167, ], ], }, ], } |
この結果を単にcount()
メソッドに渡すと、male
とfemale
の2つのグループあることから、グループ数に対応する'2'
が返される。
1 2 |
>>> $p->groupBy('gender')->count() => 2 |
これを、male
/female
各グループの要素数をカウントしたり、グループごとの身長の集計値を出したりするようにしたい。
map()メソッドの利用したグループ処理
map()
メソッドはコールバックを引数にとり、そのコールバックの引数には元のコレクションの各要素が順次与えられる。
たとえば先のグルーピングの結果をmap()
メソッドに渡すと、2つの要素male
とfemale
(その中身は連想配列の配列)が順次与えられる。これらグループ化された配列に対して、Collection
の集計メソッドを使うことができる。
1 |
$collection->groupBy('キー')->map(function($group) { return $group->処理; }); |
この場合、グループ化された1つ目のグループの各要素に関する処理、2つ目のグループの各要素に関する処理・・・と実行される。
集計例
count()の例
性別ごとの人数をカウントする例。
1 2 3 4 5 6 7 |
>>> $p->groupBy('gender')->map(function($gender) { return $gender->count(); }) => Illuminate\Support\Collection {#4333 all: [ "male" => 3, "female" => 2, ], } |
average()の例
性別ごとの平均身長を計算する例。
1 2 3 4 5 6 7 |
>>> $p->groupBy('gender')->map(function($gender) { return $gender->average('height'); }) => Illuminate\Support\Collection {#4358 all: [ "male" => 175, "female" => 165, ], } |