In Laravel, instances of Collections are used absolutely everywhere. There are lots of methods you can use on them. In the beginning, I just used the most well-known methods like map
, filter
, reduce
and first
. But there are many more, and some of them are useful shortcuts to reduce boilerplate.
Here are my top 7 methods I use all the time, but did not know when I started with Laravel.
1 keyBy
The keyBy
method adds keys to a Collection. You can specify the key by its name or with a callback:
$c = collect([
['id' => 'ID-1', 'name' => 'Alice', 'age' => 34],
['id' => 'ID-2', 'name' => 'Kevin', 'age' => 39],
]);
$c->keyBy('id');
/*
collect([
'ID-1' => ['id' => 'ID-1', 'name' => 'Alice', 'age' => 34],
'ID-2' => ['id' => 'ID-2', 'name' => 'Kevin', 'age' => 39],
])
*/
It's a neat shortcut for mapWithKeys
where the value is unchanged.
2 reject
reject
is the inverse of the well-known filter
method. It can be called with a value or a callback:
$c = collect(['Alice', 'Bob', null, 'Ben', 'Carla']);
$c = $c->reject(null);
// collect(['Alice', 'Bob', 'Ben', 'Carla']);
$c->reject(fn(string $name): bool => str_starts_with($name, 'B'));
// collect(['Alice', 'Carla']);
I use reject
to replace instances of filter
where the condition is negated because it makes the code more readable.
3 pluck
The pluck
method allows you to retrieve nested values of a Collection. If you pass a second argument to pluck
, it will use it to add keys:
$employees = collect([
['name' => 'Alice', 'position' => 'Manager', 'age' => 45],
['name' => 'Bob', 'position' => 'Programmer', 'age' => 39],
['name' => 'Carl', 'position' => 'Manager', 'age' => 51],
['name' => 'Darcy', 'position' => 'Programmer', 'age' => 28],
]);
$employees->pluck('name');
// collect(['Alice', 'Bob', 'Carl', 'Darcy'])
$employees->pluck('age', 'name');
// collect(['Alice' => 45, 'Bob' => 39, 'Carl' => 51, 'Darcy' => 28])
It's a shortcut for map
or mapWithKeys
where you just want to get some values.
4 contains
The contains
method reports whether the given value is present in the Collection. But what I did not know was, that you can also pass a key, to check for a nested value:
$employees = collect([
['name' => 'Alice', 'position' => 'Manager', 'age' => 45],
['name' => 'Bob', 'position' => 'Programmer', 'age' => 39],
['name' => 'Carl', 'position' => 'Manager', 'age' => 51],
['name' => 'Darcy', 'position' => 'Programmer', 'age' => 28],
]);
$employees->contains('name', 'Jack');
// false
$employees->contains('name', 'Bob');
// true
This can replace combinations like ->pluck('name')->contains('Jack')
, where you first retrieve values to then call contains
on them.
5 firstWhere
firstWhere
is a classic shortcut which returns the first value which matches a certain condition. The condition can be a value, callback or key with operator and operand:
$employees = collect([
['name' => 'Alice', 'position' => 'Manager', 'age' => 45],
['name' => 'Bob', 'position' => 'Programmer', 'age' => 39],
['name' => 'Carl', 'position' => 'Manager', 'age' => 51],
['name' => 'Darcy', 'position' => 'Programmer', 'age' => 28],
]);
$employees->firstWhere('age', '>' 50);
// ['name' => 'Carl', 'position' => 'Manager', 'age' => 51]
This is a shortcut for a combination of chained calls to where
and first
.
6 flatMap
The flatMap
method combines the map
and the flatten
methods. The callback given to flatMap
can modify each element. Then, all the values are flattened into a new collection.
$employees = collect([
['name' => 'Alice', 'position' => 'Manager', 'age' => 45],
['name' => 'Bob', 'position' => 'Programmer', 'age' => 39],
['name' => 'Carl', 'position' => 'Manager', 'age' => 51],
['name' => 'Darcy', 'position' => 'Programmer', 'age' => 28],
]);
$employees->flatMap(
fn($e) => strtoupper($e['name'])
);
// collect(['ALICE', 'BOB', 'CARL', 'DARCY'])
This is a shortcut for a combination of chained calls to flatten
and map
.
7 partition
partition
allows to separate the values in a Collection into two Collections, based on a callback:
$employees = collect([
['name' => 'Alice', 'position' => 'Manager', 'age' => 45],
['name' => 'Bob', 'position' => 'Programmer', 'age' => 39],
['name' => 'Carl', 'position' => 'Manager', 'age' => 51],
['name' => 'Darcy', 'position' => 'Programmer', 'age' => 28],
]);
[$m, $p] = $employees->partition(
fn($e) => $e['position'] === 'Manager'
);
$m;
/*
collect([
['name' => 'Alice', 'position' => 'Manager', 'age' => 45],
['name' => 'Carl', 'position' => 'Manager', 'age' => 51],
])
*/
$p;
/*
collect([
['name' => 'Bob', 'position' => 'Programmer', 'age' => 39],
['name' => 'Darcy', 'position' => 'Programmer', 'age' => 28],
])
*/
This can replace more complex for
loops or multiple filter
calls.
π See the Laravel Documentation for the complete reference.
π Which Collection methods are you using?
π Do you think Laravel has too many Collection methods and shortcuts?
Top comments (2)
Very nice collections methods a good Laravel programmer must be aware off. This is where collections shine over the use of plain arrays. Although when possible I like to filter and transform as much as possible in the Eloquent query itself of maximum performance.
One little suggestions on the 7th method: Partition. I would always use longer and self-describing variable names like $managers and $programmers in this example.
Thanks for the article!
Thanks a lot for your feedback!
That's certainly a valuable tip. π
Definitively true. I just wanted to keep it short for better readability on smaller screens.