Ruby map, collect and select
January 12, 2012
As a newcomer to Ruby, I have often been confused by the 3 very similar enumerators on the Array class: map, collect and select. Let’s try to figure this out using an example.
list = (1..10).to_a
p list
p list.collect { |i| i >= 3 && i <= 7 }
p list.map { |i| i >= 3 && i <= 7 }
p list.select { |i| i >= 3 && i <= 7 }

All three methods have a similar signature and take a block parameter. The map and collect methods both return an array of values returned by the block. The select method will return the actual values being iterated over if the block evaluates to true. Here it is important to know that any Ruby object can be evaluated as a boolean. (Pretty much every object will evaluate to true except nil and false)
The previous example doesn’t really show how we would use map or collect – let’s try another example.
class Person
attr_accessor :name, :surname, :age
def initialize(name,surname,age)
@name, @surname, @age = name, surname, age
end
end
people = []
people << Person.new("Daniel","Craig",43)
people << Person.new("Pierce","Brosnan",58)
people << Person.new("Sean","Connery",81)
p people.map { |p| p.surname }

Here the map method makes a bit more sense. So what’s the difference between the map and collect methods? Turns out, there is no difference. In fact, if you look at the Ruby Documentation you will see that under the hood both map and collect are implemented as the C rb_ary_collect method.
If you want to play around with my example you can find it here. Happy coding.
Tags: Ruby
Okay, so now I’m curious: in functional programming, you’ve got the equivalent of map (or .Select() in LINQ) and filter (or .Where() in LINQ). What is the Ruby equivalent of a fold (or .Aggregate() in LINQ)?
That would be the Inject method. I’ve actually blogged about that before – http://www.jacopretorius.net/2010/08/using-ruby-inject.html
I couldn’t resist but to share a tiny bit more ruby fun. You could write the first line as “list = *1..10″
That’s awesome – I’ve never seen that!
Just a head’s up: unless I’m mistaken, there’s a typo in your first example. Line 4 should be “i <= 7" to match the console output you have below it. Other than that, thanks for the post.
Well spotted. Corrected. Thanks!