Extending Laravel’s Collection With Macros

Collections are fantastic features of the framework. With the functionality that the collection offers, we can easily handle any need that a dataset requires. But still, in some cases, we may extend with custom functionality.

Understanding Macros

Macros are methods which extend the functionality of a class. For example, we can write response macros to extend the default HTTP response. Also, we can extend our collections with macros in the same way:

Collection::macro('name', function () {
    // Add functionality here
});
You may define your macros in any of your service providers.

As you see, we define the name of the macro as the first parameter; then we pass a closure with the logic as the second one. If it’s done, we can call our new method on the collection easily:

$items = collect([1, 2, 3]);

$items->name();

Now, we have the basics, let’s move on some real code.

Implementing The Missing some() Method

In JavaScript, we have the same method when we are working with arrays. It does one thing, checks if the given condition passes at least with one element. If yes, it returns true, else it returns false. So, let’s go to our AppServiceProvider‘s boot method and implement the following:

Collection::macro('some', function ($callback) {
    return !! $this->first(function ($value, $key) use ($callback) {
        return $callback($value, $key);
    });
});
Don’t forget to import the Illuminate\Support\Facades\Collection class.

As we can see, we can check against the item’s key, not only the item itself. Let’s see how:

collect([1, 2, 3, 4])->some(function ($value) {
    return $value > 2;
}); // true

collect([1, 2, 3, 4])->some(function ($value) {
    return $value > 5;
}); // false

collect([1, 2, 3, 4])->some(function ($value, $key) {
    return $key % 2 === 0;
}); // true

collect([1, 2, 3, 4])->some(function ($value, $key) {
    return $key === 'key';
}); // false

It’s important to understand; the some() method is not returning any items. It returns just a boolean that indicates if the passed condition is valid for at least one element.

Summary

Collections are very powerful, and the fact you can extend them the way you want makes them more efficient.

Here you can find the documentation about collection macros and also, you can see a bunch of implemented extensions in this package.