Eliminating Extra Code with each_with_object

I’ve been listening to Avdi Grimm’s Confident Ruby screencast and came across a function I’d never really used before: each_with_object. each_with_object allows you to iterate over a collection, passing the current item and the memo (the object that was passed in) to the block. The memo must be a mutable object, like an array or hash, not an immutable object such as a string or integer.

Here’s an example:

Without each_with_object, I have to set up a result hash, return if what I’m attempting to iterate over is a blank array, and return the result hash at the end.

def get_results(users)
  users = users.to_a
  result = {}
  return result if users.blank?

  users.each do |u|
    result[u.result_id] = u
  end

  result
end

With each_with_object, I am able to eliminate three lines of code, practically cutting my method in half. I instantiate the empty hash by passing it to each_with_object and each_with_object also does the work of returning the finished hash.

def get_results(users)
  users = users.to_a

  users.each_with_object({}) do |u, result|
    result[u.result_id] = u
  end
end