Laravel(5.4) Eloquent のクエリは Collection を返します。
初めは何だこれ?と思ったのですが、実はかなり便利だったので簡単な紹介です。
$ php artisan tinker
Psy Shell v0.8.1 (PHP 7.1.1 — cli) by Justin Hileman
>>> collect(range(1, 10));
=> Illuminate\Support\Collection {#694
all: [
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
],
}
>>> collect(range(1, 10))->filter(function($n) { return $n % 2 == 0; });
=> Illuminate\Support\Collection {#725
all: [
1 => 2,
3 => 4,
5 => 6,
7 => 8,
9 => 10,
],
}
>>> collect(range(1, 10))->filter(function($n) { return $n % 2 == 0; })->map(function($n) { return $n * 2; })
=> Illuminate\Support\Collection {#702
all: [
1 => 4,
3 => 8,
5 => 12,
7 => 16,
9 => 20,
],
}
>>> collect(range(1, 10))->filter(function($n) { return $n % 2 == 0; })->map(function($n) { return $n * 2; })->reduce(function($carry, $n) { return $carry + $n; });
=> 60
メソッドチェーンで簡単に繋げるのがいいですね。
他にもphpの標準関数の代替となる色々便利なメソッドがあるので、以下を一度見てみると良いです。
ちなみに普通の配列だと
>>> array_filter(range(1, 10), function($n) { return $n % 2 == 0; })
=> [
1 => 2,
3 => 4,
5 => 6,
7 => 8,
9 => 10,
]
>>> array_map(
... function($n) { return $n * 2; },
... array_filter(range(1, 10), function($n) { return $n % 2 == 0; })
... );
=> [
1 => 4,
3 => 8,
5 => 12,
7 => 16,
9 => 20,
]
>>> array_reduce(
... array_map(
... function($n) { return $n * 2; },
... array_filter(range(1, 10), function($n) { return $n % 2 == 0; })
... ),
... function($carry, $n) { return $carry + $n; }
... );
=> 60
とてもワンライナーでは書く気がしないし array_map
のcallbackの引数の位置が他と違って読みにくいですね。
なので Laravel 使ってて map
とか filter
とか reduce
したいなら配列はとりあえず collect
に渡しちゃえば幸せになれるっていう話でした。