Laravel 5 Collections: Transforming Collection Elements With map

Laravel 5 Collections: Transforming Collection Elements With map

Laravel 5

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 it's only arguments.

Signature

public function map(
    callable $callback
);

Example Use

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

use Illuminate\Support\Collection;

// Create a new collection instance.
$collection = new Collection([
    'first', 'second', 'third'
]);

// Create a new collection where all the strings
// in the original collection have had their case
// changed to upper-case.
$newCollection = $collection->map(function($item, $key) {
    return strtoupper($item);
});

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

object(Illuminate\Support\Collection)
  protected 'items' => 
    array
      0 => string 'FIRST'
      1 => string 'SECOND'
      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:

<?php

use \Illuminate\Contracts\Support\Arrayable;

class Product implements
{
    public $name = '';
    public $price = 0.0;
    public $onSale = false;

    /**
     * Determines if the product is on sale.
     *
     * @return bool
     */
    public function isOnSale() {
        return $this->onSale === true;
    }

    /**
     * Determines if the product is not on sale.
     *
     * @return bool
     */
    public function isNotOnSale() {
        return !$this->isOnSale();
    }

    /**
     * Converts the product to array.
     *
     * @return array
     */
    public function toArray()
    {
        return [
            'name'  => $this->name,
            'price'  => $this->price,
            'onsale' => intval($this->onSale)
        ];
    }


}

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

$products = collect([
    [
    'name'   => 'Office Chair',
    'price'  => 399.99,
    'onSale' => false
    ],
    [
        'name'   => 'Desk',
        'price'  => 199.34,
        'onSale' => true
    ]
])->transform(function ($item) {
    $product = new Product;
    $product->name = $item['name'];
    $product->price = $item['price'];
    $product->onSale = $item['onSale'];

    return $product;
})->map->toArray();

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

Start the Discussion

Leave a comment

Subscribe to our newsletter