What’s the difference between .each and .collect?

What’s the difference between .each and .collect in ruby? This can be tricky because both methods work with a collection of objects. The collect method is simply a convenience method. Like the each method, it iterates through objects in an array and somehow modifies them. But, unlike each, it also stores these modified objects into a new array. If that sounds confusing…

Here’s an example.

Let’s say you have an array:

		colors = %w{red yellow green blue orange purple pink teal}

And you want to grab each object, uppercase it, and store the result in new array. You might try:

		big_colors = colors.each { |color| color.upcase }

But this doesn’t work. It returns an array of lowercase colors because the code doesn’t know that we’d like to store each iteration in a new array. So lets refactor a bit and try this:

		big_colors = []
		colors.each do |color|
		  big_colors << color.upcase

That works. We create an empty array, grab each color, uppercase it, and add it our newly created array.

But because this is a fairly common process, ruby provides the collect method to help clean things up a bit. So we can refactor this code using collect like this:

		big_colors = colors.collect { |color| color.upcase }

A few final points.

  • Although the collect method works on arrays, it's not strictly an array method. It's part of the enumerable module which is mixed into to the array class. The enumerable module has loads of timesaving methods for working with collections. Check out the ruby documentation.
  • The collect method and the map method are interchangeable. Most people prefer collect but use whatever syntax makes more sense to you.


Your thoughts?