Laravel 5 Collections: Transforming Collection Elements With map

April 22, 2018 —John Koster

The map method applies a given $callback to each item in the collection. The $callback can modify the item which will be added to a new collection. The map method does not modify the original collection, but returns a new collection instance with all the changes. The provided $callback should accept the $item and the items $key as its only arguments.

#Signature

1public function map(
2 callable $callback
3);

#Example Use

The following code example will transform the case of each string in the collection and return a new collection instance:

1use Illuminate\Support\Collection;
2 
3// Create a new collection instance.
4$collection = new Collection([
5 'first', 'second', 'third'
6]);
7 
8// Create a new collection where all the strings
9// in the original collection have had their case
10// changed to upper-case.
11$newCollection = $collection->map(function($item, $key) {
12 return strtoupper($item);
13});

The $newCollection variable will be an instance of the Collection class and contain a value similar to following output:

1object(Illuminate\Support\Collection)
2 protected 'items' =>
3 array
4 0 => string 'FIRST'
5 1 => string 'SECOND'
6 2 => string 'THIRD'

The original $collection collection will remain unchanged.

#Using map with Higher Order Messages

In the section on the reject method we created a Product class to hold information about a product, and whether or not the product is on sale. Let's expand the Product class to implement the "Illuminate\Contracts\Arrayable" interface:

app/Product.php:

1<?php
2 
3use \Illuminate\Contracts\Support\Arrayable;
4 
5class Product implements
6{
7 public $name = '';
8 public $price = 0.0;
9 public $onSale = false;
10 
11 /**
12 * Determines if the product is on sale.
13 *
14 * @return bool
15 */
16 public function isOnSale() {
17 return $this->onSale === true;
18 }
19 
20 /**
21 * Determines if the product is not on sale.
22 *
23 * @return bool
24 */
25 public function isNotOnSale() {
26 return !$this->isOnSale();
27 }
28 
29 /**
30 * Converts the product to array.
31 *
32 * @return array
33 */
34 public function toArray()
35 {
36 return [
37 'name' => $this->name,
38 'price' => $this->price,
39 'onsale' => intval($this->onSale)
40 ];
41 }
42 
43 
44}

With the modified Product class, we can now use higher order messaging with Laravel collections like so:

1$products = collect([
2 [
3 'name' => 'Office Chair',
4 'price' => 399.99,
5 'onSale' => false
6 ],
7 [
8 'name' => 'Desk',
9 'price' => 199.34,
10 'onSale' => true
11 ]
12])->transform(function ($item) {
13 $product = new Product;
14 $product->name = $item['name'];
15 $product->price = $item['price'];
16 $product->onSale = $item['onSale'];
17 
18 return $product;
19})->map->toArray();

After the above code has executed, the $products array would contain the array representation of each of products.

Some absolutely amazing
people

The following amazing people help support this site and my open source projects ♥️
If you're interesting in supporting my work and want to show up on this list, check out my GitHub Sponsors Profile.