We can't find the internet
Attempting to reconnect
Something went wrong!
Hang in there while we get back on track
Laravel Collections are a powerful feature that allow developers to work with arrays and other data structures in an intuitive, object-oriented way. They provide a clean, expressive API to manipulate data without the need to loop through arrays manually. One of the many ways to extend the functionality of Laravel collections is through macros, which allow you to define custom methods that can be reused throughout your application.
In this blog post, we'll take a closer look at a custom macro that performs recursive mapping on arrays and objects within a collection.
Understanding the code
Here's the macro in question:
Collection::macro('recursive', function () {
return $this->map(function ($value) {
if (is_array($value)) {
return collect($value)->recursive();
}
if (is_object($value)) {
return collect((array) $value)->recursive();
}
return $value;
});
});
This macro extends Laravel's Collection
class with a new method named recursive
. The goal of this method is to
recursively map over arrays and objects within a collection, transforming all nested structures into collections
themselves.
Let's break it down step by step.
Defining the macro```php
map(function ($value) { ``` Inside the macro, the first operation is to call the `map()` method on the current collection (`$this`). The `map()` function iterates over each item in the collection and allows you to transform it. The anonymous function passed to `map()` will receive each element (`$value`) in the collection. Depending on what type of data `$value` contains, we'll handle it differently. ## Handling arrays ```php recursive(); } ``` If the current item is an array, we convert it into a collection using the `collect()` helper. This converts the array into a Laravel collection, and we call the `recursive()` method on it to ensure that any nested arrays or objects within it are also recursively transformed into collections. ## Handling objects ```php recursive(); } ``` Similarly, if the item is an object, we first cast it into an array using `(array) $value`, then wrap that array into a collection with `collect()`. As with arrays, the `recursive()` method is called to ensure that any nested structures are handled. ## Returning primitive values ```php [ 'name' => 'John Doe', 'roles' => [ ['id' => 1, 'name' => 'Admin'], ['id' => 2, 'name' => 'Editor'] ] ], 'settings' => (object) [ 'theme' => 'dark', 'notifications' => [ 'email' => true, 'sms' => false ] ] ]; $collection = collect($data)->recursive(); // Now you can work with the entire structure as collections $adminRole = $collection->get('user')->get('roles')->firstWhere('id', 1); $theme = $collection->get('settings')->get('theme'); ``` In this example, the `$data` array contains a mix of nested arrays and objects. By calling `recursive()`, we can treat everything as collections and use collection methods like `firstWhere()` and `get()` to work with the data in a clean, readable way. # Conclusion Extending Laravel's collections with a recursive macro is a great way to simplify working with complex, nested data structures. It allows you to leverage the full power of Laravel's collection API, even with deeply nested arrays and objects, without the need for manual loops or conditionals. By using this macro, your code becomes more expressive, consistent, and maintainable. If you regularly work with nested data in Laravel, this is a trick worth adding to your toolbox.If this post was enjoyable or useful for you, please share it! If you have comments, questions, or feedback, you can email my personal email. To get new posts, subscribe use the RSS feed.