#はじめに
Laravelのコレクションの便利なメソッドgroupBy
。
あれこれ触ったので、覚えたことを忘れないよう、練習問題にしてみました。
タイトルの、groupByを重ねて複数使う、最後の問3です。
すぐにやり方を知りたいという方はこちらへどうぞ。
問題
Order
, OrderDetail
, Book
, Publisher
モデルがあり、OrderDetail
からリレーションのあるBook
, Publisher
までを以下のように取得しました。
$order_details = OrderDetail::with('book.publisher')->get();
print_r(json_encode($order_details, JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT))
[
{
"id": 10001,
"order_id": 1,
"book_id": 111,
"selling_price": 3000,
"book": {
"id": 111,
"publisher_id": 11,
"name": "自習Laravel",
"list_price": 3500,
"is_electronic_book": false,
"publisher": {
"id": 11,
"name": "AA出版"
}
}
},
{
"id": 10002,
"order_id": 1,
"book_id": 222,
"selling_price": 2500,
"book": {
"id": 222,
"publisher_id": 22,
"name": "基礎から学ぶPHP",
"list_price": 3000,
"is_electronic_book": true,
"publisher": {
"id": 22,
"name": "BB出版"
}
}
},
{
"id": 10003,
"order_id": 1,
"book_id": 333,
"selling_price": 3000,
"book": {
"id": 333,
"publisher_id": 22,
"name": "パーフェクトLaravel",
"list_price": 3000,
"is_electronic_book": false,
"publisher": {
"id": 22,
"name": "BB出版"
}
}
}
]
##問1
publisher_id
でgroupBy
してください。
##問2
問1の結果では、グループ化された配列のキーはpublisher_id
の値になります。(11
や22
)
{
"11": [
{
"id": 10001,
"order_id": 1,
"book_id": 111,
"selling_price": 3000,
"book": {
"id": 111,
"publisher_id": 11,
"name": "自習Laravel",
"list_price": 3500,
"is_electronic_book": false,
"publisher": {
"id": 11,
"name": "AA出版"
}
}
}
],
"22": [
{
"id": 10002,
"order_id": 1,
"book_id": 222,
//略
これを0
から振り直してください。(JSON化した場合、以下のように出力されるようにしてください)
[
[
{
"id": 10001,
"order_id": 1,
"book_id": 111,
"selling_price": 3000,
"book": {
"id": 111,
"publisher_id": 11,
"name": "自習Laravel",
"list_price": 3500,
"is_electronic_book": false,
"publisher": {
"id": 11,
"name": "AA出版"
}
}
}
],
[
{
"id": 10002,
"order_id": 1,
"book_id": 222,
//略
##問3
まず、is_electronic_book
でgroupBy
し、その上でそれぞれの要素に対して、publisher_id
でgroupBy
してください。
##補足
必要に応じてLaravel公式ドキュメントのgroupBy
ほかを参照してください。
https://readouble.com/laravel/5.8/ja/collections.html#method-groupby
ここから先、解答になります。
...
...
...
#解答
##問1の解答
publisher_id
でgroupBy
してください。
publisher_id
は、book
をキーとする値の中に、さらにキーとして存在していました。
"book": {
"id": 111,
"publisher_id": 11,
こういった場合は、.
で繋いで指定すればOKです。
$answer1 = $order_details->groupBy('book.publisher_id');
$answer1 = $order_details->groupBy('book.publisher.id');
##問2の解答
問1の結果では、グループ化された配列のキーは
publisher_id
の値になります。(11
や22
)
これを0
から振り直してください。
キーの振り直しにはコレクションのメソッドであるvalues
が使えます。
valuesメソッドはキーをリセット後、連続した整数にした新しいコレクションを返します。
Laravel5.8 公式ドキュメント - values
https://readouble.com/laravel/5.8/ja/collections.html#method-values
$answer2 = $order_details->groupBy('book.publisher_id')
->values();
[
[
{
"id": 10001,
"order_id": 1,
"book_id": 111,
"selling_price": 3000,
"book": {
"id": 111,
"publisher_id": 11,
"name": "自習Laravel",
"list_price": 3500,
"is_electronic_book": false,
"publisher": {
"id": 11,
"name": "AA出版"
}
}
}
],
[
{
"id": 10002,
"order_id": 1,
"book_id": 222,
"selling_price": 2500,
"book": {
"id": 222,
"publisher_id": 22,
"name": "基礎から学ぶPHP",
"list_price": 3000,
"is_electronic_book": true,
"publisher": {
"id": 22,
"name": "BB出版"
}
}
},
{
"id": 10003,
"order_id": 1,
"book_id": 333,
"selling_price": 3000,
"book": {
"id": 333,
"publisher_id": 22,
"name": "パーフェクトLaravel",
"list_price": 3000,
"is_electronic_book": false,
"publisher": {
"id": 22,
"name": "BB出版"
}
}
}
]
]
##問3の解答
groupBy
を重ねて複数使うには、同じくコレクションのメソッドであるtransform
も利用することが考えられます。
$answer3 = $order_details->groupBy('book.is_electronic_book')
->transform(function ($order_detail) {
return $order_detail->groupBy('book.publisher_id')
->values(); // valuesは用途に応じてお好みで。詳細は問2参照。
});
transformメソッドはコレクションを繰り返し処理し、コレクションの各アイテムに指定したコールバックを適用します。コレクション中のアイテムはコールバックから返される値に置き換わります。
Laravel5.8 公式ドキュメント - transform
https://readouble.com/laravel/5.8/ja/collections.html#method-transform
解答例ではis_electronic_book
でgroupBy
した結果、2つの要素に分かれていますので、このtransform
を使って各々の要素に対してさらにpublisher_id
でgroupBy
しています。
[
[
[
{
"id": 10001,
"order_id": 1,
"book_id": 111,
"selling_price": 3000,
"book": {
"id": 111,
"publisher_id": 11,
"name": "自習Laravel",
"list_price": 3500,
"is_electronic_book": false,
"publisher": {
"id": 11,
"name": "AA出版"
}
}
}
],
[
{
"id": 10003,
"order_id": 1,
"book_id": 333,
"selling_price": 3000,
"book": {
"id": 333,
"publisher_id": 22,
"name": "パーフェクトLaravel",
"list_price": 3000,
"is_electronic_book": false,
"publisher": {
"id": 22,
"name": "BB出版"
}
}
}
]
],
[
[
{
"id": 10002,
"order_id": 1,
"book_id": 222,
"selling_price": 2500,
"book": {
"id": 222,
"publisher_id": 22,
"name": "基礎から学ぶPHP",
"list_price": 3000,
"is_electronic_book": true,
"publisher": {
"id": 22,
"name": "BB出版"
}
}
}
]
]
]
最後に
以上です。何問解けたでしょうか?
コレクションメソッドを使っていて、また何か気付きがあれば練習問題にしてみたいと思います