If a nested array is passed into a Laravel Collection, by default these will be threaded as normal arrays.
However, that's not always the ideal case and it would be nice if we could have nested collections in a cleaner way.
This is where this macro comes in handy.
Register this macro for example on the boot
method of your app\Providers\AppServiceProvider.php
file:
\Illuminate\Support\Collection::macro('recursive', function () {
return $this->map(function ($value) {
if (is_array($value) || is_object($value)) {
return collect($value)->recursive();
}
return $value;
});
});
Note: Tested on Laravel 5.5 and 5.6!
Usage is quite simple:
$data = [
[
'name' => 'John Doe',
'emails' => [
'john@doe.com',
'john.doe@example.com',
],
'contacts' => [
[
'name' => 'Richard Tea',
'emails' => [
'richard.tea@example.com',
],
],
[
'name' => 'Fergus Douchebag', // Ya, this was randomly generated for me :)
'emails' => [
'fergus@douchebag.com',
],
],
],
],
];
$collection = collect($data)->recursive();
I found this while researching a similar need and this is really good, but I ended up taking a slightly different approach that might be appealing to others who find their way here.
I opted for a helper function for IDE code prediction purposes but the real difference is trying to keep close to the core Collection transforming philosophy (which can collectivize various types) but then making most of it toggleable. I went ahead and threw in a depth option, too, after seeing @PascalHesselink's contribution here.