Adding attributes to laravel collection

Stefan Bogdanescu

Founder & Senior Architect · 2026-06-29

Laravel Company

Mastering Data Transformation: Adding Attributes to Laravel Collections

As developers working with Laravel, we frequently deal with collections of data—whether they originate from Eloquent models, database results, or simple arrays. One common requirement is transforming this raw data by calculating new values or adding derived attributes before processing it further. A very common task is what you described: taking existing columns (price and qty) and deriving a new column (amount).

This post dives into the most effective and idiomatic ways to add custom attributes to your Laravel Collections, addressing the specific challenges encountered when trying to modify items within an iteration loop.

The Challenge with Iteration and Modification

You are attempting to iterate over your collection and update the individual arrays within it:

$collection->each(function ($item) {
    $item['amount'] = $item['price'] * $item['qty'];
});

While this approach seems logically sound, you correctly identified a potential pitfall. When working with collections in PHP and Laravel, modifying the elements directly within an iteration loop can sometimes lead to unexpected behavior, especially if you are dealing with complex nested structures or when trying to ensure immutability—a core principle in modern object-oriented programming. The issue often lies in how the collection manages its internal references during the iteration process.

The key takeaway here is that while modifying the $item array inside the loop technically changes the data, using methods like each() for bulk transformation can be less readable and less efficient than leveraging Laravel's built-in functional programming tools.

Solution 1: The Idiomatic Approach – Using map()

The most recommended way to transform every item in a Laravel Collection into a new set of items is by using the map() method. The map() method iterates over the collection and applies a callback function to each element, returning a new collection containing the results. This approach adheres to functional programming principles, making your code cleaner, safer, and easier to reason about.

Instead of trying to mutate the original items in place, we create a new collection with the desired structure.

Here is how you would calculate the amount attribute using map():

$collection = collect([
    ['curr' => 'IDR', 'price' => 5500000.0, 'rate' => 14325.803, 'qty' => 2],
    ['curr' => 'IDR', 'price' => 1500000.0, 'rate' => 14325.803, 'qty' => 1]
]);

$transformedCollection = $collection->map(function ($item) {
    // Calculate the new attribute and return a new array with all original data plus the new one.
    $item['amount'] = $item['price'] * $item['qty'];
    return $item;
});

// Output the result
dd($transformedCollection->toArray());

Why map() is superior: It guarantees that you are working with a clean, derived set of data. This aligns perfectly with best practices when manipulating collections in Laravel. For more complex transformations, this functional approach is highly encouraged (as seen in guides on writing robust code on the Laravel Company).

Solution 2: In-Place Mutation using each() or foreach

If, for specific performance reasons or strict memory constraints, you absolutely must modify the original collection directly without creating a new one, you can use a standard foreach loop or the each() method. While map() is preferred, these methods are useful when in-place mutation is explicitly required.

$collection = collect([
    ['curr' => 'IDR', 'price' => 5500000.0, 'rate' => 14325.803, 'qty' => 2],
    ['curr' => 'IDR', 'price' => 1500000.0, 'rate' => 14325.803, 'qty' => 1]
]);

$collection->each(function ($item) {
    // Directly modify the array within the collection
    $item['amount'] = $item['price'] * $item['qty'];
});

dd($collection->toArray());

Conclusion

When adding attributes to a Laravel Collection, always default to functional methods like map() whenever possible. They promote cleaner, more testable, and less error-prone code by focusing on transformation rather than in-place mutation. While using each() can achieve the result, understanding the difference between creating a new collection (map()) and modifying an existing one is fundamental to writing high-quality Laravel applications. By embracing these patterns, you ensure your data flows smoothly and efficiently throughout your application.