Laravel: Understanding Collections’ Higher Order Messages

… and the beauty of them.

Italo Baeza Cabrera
3 min readApr 23, 2020

If may think that enough tinkering around Laravel’s Collections too much have made you some kind of Collection expert, but Higher Order Messages are one level above in understanding.

One thing I couldn’t grasp, and probably you either if you are reading this, is how they work and what problem they try to solve, but falter not, these are relatively easy to understand when you think about them as proxies to the real methods.

Get off my lawn, you dirty closure!

Higher Order Messages are basically properties that act like you were doing a very short closure. To better exemplify, let’s say we want to filter all users who are not admin.

$users = collect([
1 => [
'name' => 'John',
'age' => 31
'is_admin' => false,
],
2 => [
'name' => 'Mike',
'age' => 16
'is_admin' => true,
],
3 => [
'name' => 'Carmen',
'age' => 58
'is_admin' => false,
],
4 => [
'name' => 'Abby',
'age' => 24
'is_admin' => true,
],
]);

You can see that Mike and Abby are admins because the is_admin is true, so the first thing you could do to filter them should be to call the filter method of the Collection to return those who are inside another Collection instance.

$admins = $users->filter(function (array $user) {
return $user['is_admin'];
});

While that line may work for some, we can make the filter a one line. The filter method as a Higher Order Message by the same name. It will take the value we are using to “get” as the what the closure should return for each item in the collection, being a property or an array key.

$admins = $users->filter->is_admin;

And that’s it, it’s very simple.

What about sum, for example?

Some methods do not return collections, and that’s fine. For example, the sum method returns the result of a sum on the value of each item.

In this case, we can sum the users who are admins:

$admins = $users->sum(function (array $user) {
return $user['is_admin'] ? 1 : 0;
});
// 2

We can make that whole call into one line, since the sum method actually does an additive operation in PHP which is compatible with booleans, where true is 1 and false is 0. So, yes, we can sum booleans without any problem.

$admins = $users->sum->is_admin; // 2

Can you use methods? With arguments?

Higher Order Collection are also compatible with methods, including arguments to them. The method you pass will be used for each item, so let’s make an example.

This User class has a convenient method that returns true or false if the age is above to what we’re asking.

class User extends Model
{
public function ageAbove(int $age)
{
return $this->age > $age;
}
}

Let’s assume we have a collection of these User class instances. The old nasty way to filter them would be using a closure to execute on each of them.

$users = User::all();$adults = $users->filter(function (User $user) {
return $user->ageAbove(21);
});

And it gets more verbose when we have to include the age from a variable outside the closure.

$adults = $users->filter(function (User $user) use ($age) {
return $user->ageAbove($age);
});

But that can be, again, become a one line:

$adults = $users->filter->ageAbove(21);

And that’s all folks!

--

--

Italo Baeza Cabrera

Graphic Designer graduate. Full Stack Web Developer. Retired Tech & Gaming Editor. https://italobc.com