My team at Spatie is currently building Mailcoach, a solution to self host your e-mail newsletter. Mailcoach can be used as stand alone software or as a Laravel package. Subscribe now at Mailcoach to get a notification as soon as we release it.

Avoid nesting using the crossJoin and eachSpread collection functions

Original – by Freek Van der Herten – 1 minute read

While working on a package I found myself trying to combine some data. This is what my code looked like. Assume that $locales and $fields are arrays that are already populated.

collect($locales)->each(function (string $locale) {
    collect($fields)->each(function (Field $field) use ($locale) 
       $this->doSomeWork($locale, $field); 
    });
});

Sure, it's pretty already pretty clear, but there are also two cool collection methods that allow us to do the same thing. crossJoin creates a new collection with all possible combinations of the input given. eachSpread is a method that will pass each nested item as an argument to the callback.

Using those functions the code above can be rewritten as this:

collect($this->locales)
    ->crossJoin($this->originalFields)
    ->eachSpread(function (string $locale, Field $field) {
        $this->doSomeWork($locale, $field);
    });

Even though the first version of the code was pretty clear, I like this one better. There's no nesting involved here and we avoided the need for that damn use to import a variable.

Thanks Seb for this refactor!

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

Follow me on Twitter. I regularly tweet out programming tips, and what I myself have learned in ongoing projects.

Every two weeks 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.