Mike Classic

Collection Class: Array Mapping

Thank you, Laravel, for your Illuminate package. Thank you for the Collection class.

Recently I had a situation where I had to query a database, return some results, and convert the entries from objects into strings. In vanilla PHP, one can do this with something as simple as array_map.

I figured, since I was working with the Laravel framework, that I'd use the Illuminate\Support\Collection class, as I knew it was quite easy to use, handy, and a great enhancement to PHP's array functions.

While I was digging through the Collection class source, I noticed different array mapping functions, so I had to determine which was best to use for my situation.

Each()

This method simply executed the array_map function with no frills. It didn't save it either. So basically the user uses it to perform external actions, such as building a new array or object with it, used outside of the existing Collection instance.

    /* Collection method: */
    public function each(Closure $callback) {
        array_map($callback, $this->items);
    }

    /* Sample usage. */
    $percentages = array();
    $collection->each(function($item) use (&$percentages)
    {
        $percentages[] = $item * 100;
    });

Map()

The map method also uses array_map, but passes you the array keys as well, in case you need to use them. Additionally, it returns a new Collection instance. This could be useful if, say, you want to further manipulate your new array but want to preserve the existing instance as well.

    /* Collection method: */
    public function map(Closure $callback)
    {
        return new static(array_map($callback, $this->items, array_keys($this->items)));
    }

    /* Sample usage. */
    $newCollection = $collection->map(function($item, $key)
    {
        return array($key => $item + 1);
    });

Transform()

And finally, we come to transform. This one was my saviour tonight. It allowed me to manipulate the Collection in place. That is, it also uses array_map but manipulates the array in-place. This allowed me, in my example, to convert an array of objects into an array of strings without having to waste memory by creating a second array.

    /* Collection method: */
    public function transform(Closure $callback)
    {
        $this->items = array_map($callback, $this->items);

        return $this;
    }

    /* Sample usage. */
    /* Registrations before:
     * $registrations[0] = new \stdClass() { public $registration_id = '1234' };
     * Registrations after:
     * $registrations[0] = '1234';
     */
    $registrations->transform(function($item)
    {
        return (string) $item->registration_id;
    });
comments powered by Disqus