Laravel Tutorial · Database and Eloquent · Lesson 17 of 27
Laravel Collections
Laravel's Collection class wraps arrays with dozens of chainable methods: map, filter, groupBy, sum, sortBy, pluck, keyBy, chunk and more. Eloquent results are collections too.
Working with collections
collect([...]) wraps an array; every Eloquent get() returns one. Methods return new collections, so you can chain them:
| Method | Does |
|---|---|
map, filter, reject, each |
Transform, keep, drop, loop |
pluck('name'), keyBy('id'), groupBy('status') |
Reshape |
sum, avg, max, min, count |
Aggregate (with a key or callback) |
sortBy, sortByDesc, unique, values |
Order and clean |
first, firstWhere, contains, every |
Find and test |
chunk(3), take(5), partition(fn) |
Split |
implode(', '), toArray(), toJson() |
Output |
Lazy collections (LazyCollection, cursor()) process huge datasets without loading everything into memory.
<?php
$orders = collect([
['id' => 1, 'customer' => 'Ana', 'status' => 'paid', 'total' => 45.00],
['id' => 2, 'customer' => 'Ben', 'status' => 'pending', 'total' => 12.50],
['id' => 3, 'customer' => 'Ana', 'status' => 'paid', 'total' => 99.00],
['id' => 4, 'customer' => 'Cleo', 'status' => 'refunded', 'total' => 30.00],
['id' => 5, 'customer' => 'Ben', 'status' => 'paid', 'total' => 25.00],
]);
$paid = $orders->where('status', 'paid');
echo 'paid revenue: ', $paid->sum('total'), ', average: ', round($paid->avg('total'), 2), "\n";
echo 'customers: ', $orders->pluck('customer')->unique()->sort()->implode(', '), "\n";
$byCustomer = $paid->groupBy('customer')->map(fn ($group) => $group->sum('total'))->sortDesc();
foreach ($byCustomer as $name => $total) {
echo " $name: $total\n";
}
[$big, $small] = $orders->partition(fn ($o) => $o['total'] >= 30);
echo 'big orders: ', $big->pluck('id')->implode(','), ' | small: ', $small->pluck('id')->implode(','), "\n";
echo 'order 3 by key: ', $orders->keyBy('id')->get(3)['customer'], "\n";
echo 'any refunds? ', $orders->contains('status', 'refunded') ? 'yes' : 'no', "\n";
echo 'pages of 2: ', $orders->chunk(2)->map(fn ($c) => $c->pluck('id')->implode('+'))->implode(' | '), "\n";
echo json_encode($orders->map(fn ($o) => strtoupper($o['customer'][0]).$o['id'])->values()), "\n";
Output
paid revenue: 169, average: 56.33 customers: Ana, Ben, Cleo Ana: 144 Ben: 25 big orders: 1,3,4 | small: 2,5 order 3 by key: Ana any refunds? yes pages of 2: 1+2 | 3+4 | 5 ["A1","B2","A3","C4","B5"]
Run this on your computer — see “Get Started” for setup.
Test yourself
Which collection method groups orders into a nested collection per status?
pluck('status')groupBy('status')keyBy('status')chunk('status')
Show answer
Answer: groupBy('status')