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' => [
'[email protected]',
'[email protected]',
],
'contacts' => [
[
'name' => 'Richard Tea',
'emails' => [
'[email protected]',
],
],
[
'name' => 'Fergus Douchebag', // Ya, this was randomly generated for me :)
'emails' => [
'[email protected]',
],
],
],
],
];
$collection = collect($data)->recursive();
Hey @brunogaspar, I'm trying to understand how this recursive macro works internally.
When you call recursive() on a collection, the first layer of arrays gets converted to collections. The inner layers get converted when for example, mapping or printing (toArray) the entire collection.
Maybe I'm missing something here.
When a value is an array or object, you return
collect($value)->recursive()
. This doesn't run right away, correct?Oh I just got it! When you return the
collect($value)->recursive()
it actually runs the recursive() function on the $value. The 4value gets converted to a collection and all its children if any an array, will also get converted to a collectionThanks