Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Recursive Laravel Collection Macros

What?

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.

Setup

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!

How

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();
@ddavaham

This comment has been minimized.

Copy link

commented Dec 2, 2017

I work with a rest API returns objects. I usually cast these object to a collections. They tend to nested arrays or objects, so I added support for objects as well. I would have of done a pull request, but I do not think that Gist support them

if (is_object($value)) {
    return collect($value)->recursive();
}

Complete Code

        \Illuminate\Support\Collection::macro('recursive', function () {
            return $this->map(function ($value) {
                if (is_array($value)) {
                    return collect($value)->recursive();
                }
                if (is_object($value)) {
                    return collect($value)->recursive();
                }

                return $value;
            });
        });
@brunogaspar

This comment has been minimized.

Copy link
Owner Author

commented Dec 6, 2017

@ddavaham I've done the suggested change on the OP.

Thanks!

@seanmangar

This comment has been minimized.

Copy link

commented Jan 4, 2018

Had the same issue. Thanks for this Bruno! 👍

@robsontenorio

This comment has been minimized.

Copy link

commented Jun 16, 2018

@4hm3d same issue. can you share full macro code?

@medteck

This comment has been minimized.

Copy link

commented Jun 22, 2018

Had to deal with a large amount of recursive JSON data! This fixed my problem.
Thanks 👍

@adrienne

This comment has been minimized.

Copy link

commented Jun 24, 2018

Please consider submitting a pull request to these folks: https://github.com/spatie/laravel-collection-macros who have a super handy collection of macros that this would be a great fit for!

@roni-estein

This comment has been minimized.

Copy link

commented Nov 27, 2018

Thx

@MarcHef

This comment has been minimized.

Copy link

commented Jan 17, 2019

Thx

@Mombuyish

This comment has been minimized.

Copy link

commented Mar 17, 2019

Thanks!

@brunogaspar

This comment has been minimized.

Copy link
Owner Author

commented Mar 31, 2019

Hey peeps!

Since i've saw a bit of "demand" for this helper/macro to be in a more installable way and considering Spatie refused a few pull requests to add this macro, i've decided to create my own package.

https://github.com/werxe/laravel-collection-macros

Feel free to use it and suggest new macros, i'm sure i'll be adding a few more.

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.