Ruby, PHP and the Array Map method

Due to my work and my academia commitments I find myself very often switching from Ruby to PHP and back again. This is making me more and more accustomed to the substantial differences between these two languages.

Among these differences the handling of collections is perhaps one of the biggest I found till now.

For example in Ruby there is a module (i.e. an object) called Enumerable that exposes a lot of useful helpers and utilities to work with collections (i.e. objects).

One of these utilities is map. The concepts underlined are pretty much the same across languages and are summarized here.

While working on a collection of objects, in particular a Nokogiri::XML::NodeSet, I recently had the need to extend the map behavior to get a collection of non duplicated Nokogiri::XML::Node elements.

This is actually a pretty straightforward need that can be satisfied by calling the Array uniq method and providing it with a block containing the logic regarding the uniqueness of the elements.

So I wrote the following little helper Module that I included inside the Nokogiri::XML::NodeSet class:


module UniqueMapper
    def map_unique unique_id, &block
        self.map(&block).compact.uniq{ |x| x.send(unique_id) }
    end
end

I simply defined a brand new map method that takes a parameter and a block as arguments. The first is used inside the uniq block to “describe” the uniqueness criteria while the latter is passed directly to the standard map method. The compact method is used in between to remove nil values from the array.

Thanks to Ruby “awesomeness” this was pretty easy to accomplish.

Now, luckily for me I don’t have to satisfy a similar need in PHP yet.

What I needed instead was to pass to the callback of the PHP map function (i.e. array_map) some additional arguments.

While doing this I discovered something awkward. You need to prepare an array for every additional argument composed by the argument value with a length equal to the length of the array that should be “mapped”.

Here’s an example:


array_map(
'callback', 
$array_to_map, 
array_fill(0, count($array_to_map), $first_additional_argument),
array_fill(0, count($array_to_map), $second_additional_argument),
...
);

The first argument (i.e. “callback”) represents the name of the function used to map the second argument (i.e. $array_to_map). The others arguments are the ones taken by the “callback” function.

This solution is everything but pretty and probably (I hope!) there’s a more elegant one out there.

With this article I wanted to show my personal (and limited) experience with the map utility in Ruby and PHP and how these languages differs profoundly from each other.

Cheers!

Leave a Reply

wpDiscuz