Transforming data in Laravel usually begins with the map() method on collections, which iterates over every element executing a callback, and returns a new collection with the resulting values.
Now, if your callback returns an array or another collection for each item, you'll have another level of nesting that you need to remove (by using something like ->map(...)->flatten(1)), but Laravel provides a cleaner solution for doing this: the flatMap() method.
Table of Contents
How map() Behaves with Nested Data
The traditional map() method simply iterate over your collestion and returns whatever your collection date returns as shown below.
$users = collect([
['name' => 'Kishan', 'roles' => ['admin', 'developer']],
['name' => 'Aman', 'roles' => ['editor']],
]);
$roles = $users->map(function ($user) {
return $user['roles'];
});
// Output: [['admin', 'developer'], ['editor']]
To get a single flat list of roles, we can add flatten() or collapse():
$roles = $users->map(function ($user) {
return $user['roles'];
})->flatten(1);
// Output: ['admin', 'developer', 'editor']
The Solution: flatMap()
flatMap() combines these both methods functionality into a single operation. It loops through the collection, passes each item through your closure, and flattens the result by one level as shown below.
$roles = $users->flatMap(function ($user) {
return $user['roles'];
});
// Output: ['admin', 'developer', 'editor']
Real-World Example: Extracting Tags from Posts
For example you have a blogging website and each blogs may contains multiple tags attached to it. Then we can do something as below.
$posts = Post::with('tags')->get();
$uniqueTagNames = $posts->flatMap(function ($post) {
return $post->tags->pluck('name');
})->unique()->values();
Each post yields an array of tag names, and flatMap() automatically unpacks them into a single-dimensional stream for chaining.
Key Differences at a Glance
| Feature | map() | flatMap() |
|---|---|---|
| Output Structure | Preserves return shape (nested arrays stay nested). | Flattens the resulting array by one level. |
| Closure Return Expectation | Can return any primitive, object, or array. | Closure should return an iterable (array or collection). |
| Equivalent Code | array_map() |
$collection->map(...)->collapse() |
| Best Used For | 1-to-1 data transformation. | 1-to-many relationship unpacking into a flat list. |
Summary
When you need to transform items into a single value, use map(). But when you have to expand list items and make a flat collection out of them, use flatMap() instead of using map() and flatten().
Thank you for reading this article 😊
For any query, do not hesitate to comment 💬