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?
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; });
array_map
wants, as the name suggests, arrays. It's not called iterator_map
after all. ;)
Apart from iterator_to_array()
, which produces a potentially large temporary array, there's no trick to make iterable objects work with array_map
.
The Functional PHP library has a map
implementation which works on any iterable collection.
If you're not interested in creating a new array that is a function mapped over the original array, you could just use a foreach loop (because you implement Iterator
).
foreach($item in $myCollection) {
$item->method1();
$item->method2();
}
if you actually want to use map, then I think you'll have to implement your own. I would suggest making it a method on Collection, eg:
$mutatedCollection = $myCollection->map(function($item) {
/* do some stuff to $item */
return $item;
});
I would ask yourself if you really want to use map
or do you really just mean foreach
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With