Lifetime access is $100 off. Available for a limited time.Join here →

Recursively convert an array and its children to a Collection in Laravel

November 13th, 2021

If you're dealing with plain array data, it often makes sense to convert it to a Laravel Collection so you can make use of the myriad helpers on the Collection class

Whether you're using new Collection([]) or collect([]), I'm going to show you how to not only create a collection, but also iterate recursively and include children.

A bit of background on this first. Let's say you have the following array.

['nike', 'adidas', 'under armour']

If you convert this to a collection, you'll end up with the following.

Illuminate\Support\Collection {#386
    #items: array:3 [
    0 => "nike"
    1 => "adidas"
    2 => "under armour"
    ]
}

But what if the array was multi-dimensional (i.e. had children)?

['brands' => ['nike', 'adidas', 'under armour']]

You'd still end up with native arrays inside the collection.

Illuminate\Support\Collection {#386
    #items: array:1 [
    "brands" => array:3 [
        0 => "nike"
        1 => "adidas"
        2 => "under armour"
    ]
    ]
}

This is fine for most cases, but if you need the power of collections to iterate and work through a multidimensional array, you'll need to add a macro!

Luckily, Laravel's Collection class is macroable, meaning we can add our own methods.

So let's add a recursive macro to deal with this recursive functionality.

use Illuminate\Support\Collection;

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

        return $value;
    });
});

Add this to the boot method of a service provider (like AppServiceProvider).

To use this new method, just chain it on when creating a new collection from an array.

collect(['brands' => ['nike', 'adidas', 'under armour']])->recursive();

Taking this for a spin with the multidimensional example from earlier, here's what we end up with.

Illuminate\Support\Collection {#390
    #items: array:1 [
    "brands" => Illuminate\Support\Collection {#393
        #items: array:3 [
        0 => "nike"
        1 => "adidas"
        2 => "under armour"
        ]
    }
    ]
}

Now the inner brands key is also a collection!

Because it's recursive, this functionality works for any level deep.

Happy recursing!

Thanks for reading! If you found this article helpful, you might enjoy our practical screencasts too.
Author
Alex Garrett-Smith
Share :

Comments

No comments, yet. Be the first to leave a comment.

Table of contents

Tagged under