Laravel Collection is one of the most powerful features that beginner developers often underestimate. A Collection is an elegant wrapper for working with array data, providing dozens of built-in methods that make data manipulation easy without writing manual loops. After reading this article, you'll use Collection more intelligently and efficiently.
What Is a Laravel Collection?
A Collection is an instance of the Illuminate\Support\Collection class. Every Eloquent query that returns multiple rows automatically becomes a Collection. You can also create a Collection manually:
<?php
use Illuminate\Support\Collection;
// From a plain array
$collection = collect([1, 2, 3, 4, 5]);
// From an associative array
$users = collect([
['name' => 'Budi', 'age' => 25, 'city' => 'Jakarta'],
['name' => 'Ani', 'age' => 30, 'city' => 'Bandung'],
['name' => 'Caca', 'age' => 22, 'city' => 'Jakarta'],
['name' => 'Dodi', 'age' => 28, 'city' => 'Surabaya'],
]);
The map() Method — Transforming Data
map() iterates over each item and returns a new Collection of the transformed results:
// Convert all names to uppercase
$upperNames = $users->map(function ($user) {
return strtoupper($user['name']);
});
// Result: ['BUDI', 'ANI', 'CACA', 'DODI']
// With an arrow function (PHP 7.4+)
$prices = collect([10000, 25000, 15000]);
$discounted = $prices->map(fn($price) => $price * 0.9);
// Result: [9000, 22500, 13500]
The filter() Method — Filtering Data
filter() returns a Collection containing only the items that pass a condition:
// Filter users from Jakarta
$jakartaUsers = $users->filter(fn($user) => $user['city'] === 'Jakarta');
// Result: Budi and Caca
// Filter without a callback: remove falsy values (null, false, 0, '')
$clean = collect([1, null, 2, false, 3, 0])->filter();
// Result: [1, 2, 3]
// Re-index after filtering
$reindexed = $jakartaUsers->values();
The groupBy() Method — Grouping Data
groupBy() is very useful for grouping data by a certain key:
$byCity = $users->groupBy('city');
/*
Result:
[
'Jakarta' => [Budi, Caca],
'Bandung' => [Ani],
'Surabaya' => [Dodi],
]
*/
// Access each group
$jakartaGroup = $byCity->get('Jakarta');
$jakartaGroup->count(); // 2
The pluck() Method — Getting a Single Column's Values
// Get all names
$names = $users->pluck('name');
// Result: ['Budi', 'Ani', 'Caca', 'Dodi']
// Create a key-value pair
$nameById = User::all()->pluck('name', 'id');
// Result: [1 => 'Budi', 2 => 'Ani', ...]
// Useful for a dropdown select
<select name="user_id">
@foreach($nameById as $id => $name)
<option value="{{ $id }}">{{ $name }}</option>
@endforeach
</select>
The reduce() Method — Accumulating a Value
// Calculate the total price
$items = collect([
['name' => 'Book', 'price' => 50000, 'qty' => 2],
['name' => 'Pencil', 'price' => 5000, 'qty' => 5],
['name' => 'Bag', 'price' => 200000, 'qty' => 1],
]);
$total = $items->reduce(function ($carry, $item) {
return $carry + ($item['price'] * $item['qty']);
}, 0);
// Result: 325000
Method Chaining — Collection's Real Power
The biggest advantage of Collection is method chaining, which makes code more expressive:
// Get the names of users from Jakarta, aged over 23, sorted alphabetically
$result = $users
->filter(fn($u) => $u['city'] === 'Jakarta')
->filter(fn($u) => $u['age'] > 23)
->sortBy('name')
->pluck('name')
->values();
// Result: ['Budi']
Other Useful Methods
sum('price')— sum the values of a certain key.avg('age')— the average value.max('age')/min('age')— the maximum/minimum value.sortBy('name')/sortByDesc('age')— sort the data.unique('city')— remove duplicates.chunk(3)— split the Collection into small chunks.contains('name', 'Budi')— check whether a matching item exists.first()/last()— get the first/last element.toArray()— convert back into a plain PHP array.toJson()— convert into a JSON string.
Lazy Collection for Large Data
If you need to process very large data (hundreds of thousands of rows), use LazyCollection to keep memory efficient:
use Illuminate\Support\LazyCollection;
// Process a large file line by line
LazyCollection::make(function () {
$handle = fopen('data.csv', 'r');
while (($line = fgets($handle)) !== false) {
yield $line;
}
})->chunk(1000)->each(function ($chunk) {
// Process per 1000 rows
});
Conclusion
Laravel Collection changes the way you think about data manipulation. Instead of writing nested foreach loops, use expressive, chainable Collection methods. From map(), filter(), and groupBy() to reduce() — they're all available out of the box. The more familiar you are with Collection, the cleaner and more readable your Laravel code becomes.