Oh Dear is the all-in-one monitoring tool for your entire website. We monitor uptime, SSL certificates, broken links, scheduled tasks and more. You'll get a notifications for us when something's wrong. All that paired with a developer friendly API and kick-ass documentation. O, and you'll also be able to create a public status page under a minute. Start monitoring using our free trial now.

Some handy collection macros

Original – by Freek Van der Herten – 4 minute read

Laravel's collection class is truly wonderful. It contains a lot of handy methods and you can create some very elegant code with it. In client projects I found myself adding the same macro's over and over again. That's why my colleague Seb and I took some time to create a package aptly called laravel-collection-macros that contains those macros. You can view the source code and installation instructions on GitHub.

To install the package you'll only need to pull it via composer and register the service provider. With that out of the way the collection class in your project will gain these methods:

dd

This macro dumps the contents of the collection and terminates the script. It makes debugging a collection much easier.

collect([1,2,3])->dd();

split

Image you need to render some items in a given amount of columns. With the split macro you can split the collection into a the given number of groups.

$collection = collect(['a', 'b', 'c', 'd', 'e', 'f'])->split(3);

$collection->count(); // returns 3

$collection->first(); // returns a collection with 'a' and 'b';
$collection->last(); // returns a collection with 'e' and 'f';

validate

With this macro you can validate all items inside a collection. You can pass a validate rule to it.

collect(['sebastian@spatie.be', 'bla'])->validate('email'); // returns false
collect(['sebastian@spatie.be', 'freek@spatie.be'])->validate('email'); // returns true

//for fine grained control you may also pass a closure.
collect(['foo', 'foo'])->validate(function ($item) {
   return $item === 'foo';
}); // returns true

range

Creates a new collection instance with a range of numbers. This functions accepts the same parameters as PHP's standard range function.

collect()->range(1, 3)->toArray(); //returns [1,2,3]

ifAny

The passed callable will only be called if the collection isn't empty. The entire collection will be returned.

collect()->ifAny(function() { // empty collection so this won't get called
   echo 'Hello';
});

collect([1, 2, 3])->ifAny(function() { // non-empty collection so this will get called
   echo 'Hello';
});

ifEmpty

This is the opposite of ifAny.

collect()->ifEmpty(function() { // empty collection so this will called
   echo 'Hello';
});

collect([1, 2, 3])->ifEmpty(function() { // non-empty collection so this won't get called
   echo 'Hello';
});

none

Checks whether a collection doesn't contain any occurrences of a given item, key-value pair, or passing truth test. The function accepts the same parameters as the contains collection method.

collect(['foo'])->none('bar'); // returns true
collect(['foo'])->none('foo'); // returns false

collect([['name' => 'foo']])->none('name', 'bar'); // returns true
collect([['name' => 'foo']])->none('name', 'foo'); // returns false

collect(['name' => 'foo'])->none(function ($key, $value) {
   return $key === 'name' && $value === 'bar';
}); // returns true

groupByModel

This is a very opinionated macro. It works similar to groupBy, but it'll group the collection by an Eloquent model instead of a string. Imagine that your project contains an Article model that has a relationship with a Category model. In your view you want to render all articles grouped by category.

Sure you could to this:

Article::all()->groupBy(function(Article $article) {
  return $article->category->name;
});

That'll work but the downside of it is that you only have the name of the category left when looping over the resulting collection.

When using the groupByModel macro you still can get to all properties of the category.

<br />Article::all()->groupByModel('category');

//this returns something like this
// [
//     [
//         'category' => $category,
//         'items' => [
//             [ // articles models with the category],
//         ],
//     ],
//     [
//         'category' => $category2,
//         'items' => [
//             [ // article models with $category 2 ],
//         ],
//     ],
// ];


Want to know more about the package, then head over to GitHub to learn all the options. We do accept new macro's to the package, so if you've got a macro lying around that could be useful to your fellow artisans, send us a PR.

You can take a look at the Laravel packages we previously made on our website. If one of our packages makes it to your production environment don't forget to send us a postcard.

Stay up to date with all things Laravel, PHP, and JavaScript.

You can follow me on these platforms:

On all these platforms, regularly share programming tips, and what I myself have learned in ongoing projects.

Every month I send out a newsletter containing lots of interesting stuff for the modern PHP developer.

Expect quick tips & tricks, interesting tutorials, opinions and packages. Because I work with Laravel every day there is an emphasis on that framework.

Rest assured that I will only use your email address to send you the newsletter and will not use it for any other purposes.

Comments

What are your thoughts on "Some handy collection macros"?

Comments powered by Laravel Comments
Want to join the conversation? Log in or create an account to post a comment.