Transforming hashes in Ruby without inject or each_with_object

Written . Tagged Ruby.

Want to transform a Ruby hash, changing every key or value? There are better options than inject or each_with_object.

Those are relatively low-level methods that expose details (like a reference to the hash itself) that you often don’t need:

inject.rb
{ a: 1, b: 2 }.inject({}) { |h, (k, v)| h.merge(k => v * 2) }
# => { a: 2, b: 4 }
each_with_object.rb
{ a: 1, b: 2 }.each_with_object({}) { |(k, v), h| h[k] = v * 2 }
# => { a: 2, b: 4 }

If you’re on Ruby 2.4+ and only want to change the hash values, you can instead use transform_values:

transform_values.rb
{ a: 1, b: 2 }.transform_values { |v| v * 2 }
# => { a: 2, b: 4 }

If you’re on Ruby 2.0+, you can use map and to_h:

map_and_to_h.rb
{ a: 1, b: 2 }.map { |k, v| [ k, v * 2 ] }.to_h
# => { a: 2, b: 4 }