array_map on collection with array interfaces?

f1ames picture f1ames · Apr 29, 2013 · Viewed 18.6k times · Source

I have a class called Collection which stores objects of same type. Collection implements array interfaces: Iterator, ArrayAccess, SeekableIterator, and Countable.

I'd like to pass a Collection object as the array argument to the array_map function. But this fails with the error

PHP Warning: array_map(): Argument #2 should be an array

Can I achieve this by implementing other/more interfaces, so that Collection objects are seen as arrays?

Answer

Ja͢ck picture Ja͢ck · Apr 29, 2013

The array_map() function doesn't support a Traversable as its array argument, so you would have to perform a conversion step:

array_map($fn, iterator_to_array($myCollection));

Besides iterating over the collection twice, it also yield an array that will not be used afterwards.

Another way is to write your own map function:

function map(callable $fn)
{
    $result = array();

    foreach ($this as $item) {
        $result[] = $fn($item);
    }

    return $result;
}

Update

Judging by your use-case it seems that you're not even interested in the result of the map operation; therefore it makes more sense to use iterator_apply().

iterator_apply($myCollection, function($obj) {
    $obj->method1();
    $obj->method2();

    return true;
});