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();
Thanks, that was very helpful! 👍
I've tweaked the macro so that it wraps the
$value
using the lowest inheritance class.For example, if you extend the Collection class like this:
Then you can recursively wrap a nested array like that:
And now all nested collections will be instances of
Knowledge
.