Today I discovered Ruby’s each_with_object method and I thought it was pretty nifty. Here is how it works.

An example with an output array of doubled values:

nums = [1, 2, 3, 4, 5]

nums.each_with_object([]) do |num, output|
output < < (num * 2)
end

#=> [2, 4, 6, 8, 10]

You may say, “meh, this works one heck of a lot like map but clunkier.” And you’d be right.

nums = [1, 2, 3, 4, 5]

nums.map do |num|
num * 2
end

#=> [2, 4, 6, 8, 10]

But if you want to output a hash, you may start to see its value. Here we’ll output a hash that counts instances of a letter in an array:

letters = %w[a a a b c c d e e e f f f f g g]

letters.each_with_object({}) do |letter, output|
output[letter] ? output[letter] += 1 : output[letter] = 1
end

#=> {"a"=>3, "b"=>1, "c"=>2, "d"=>1, "e"=>3, "f"=>4, "g"=>2}

Now that’s pretty nifty. The other option is to use plain each, hoist the output variable in advance, and then return it. Like this:

output = {}

letters.each do |letter|
output[letter] ? output[letter] += 1 : output[letter] = 1
end

output

#=> {"a"=>3, "b"=>1, "c"=>2, "d"=>1, "e"=>3, "f"=>4, "g"=>2}

But this ain’t JavaScript, so why hoist if you don’t have to? ;)

If you’d like a few more examples, check out this post by Agnieszka Matysek of womanonrails.com.