rubyguides

Hash#invert

Synopsis

hash.invert -> new_hash

Returns a new map where each key-value pair is swapped: values become keys, and keys become values.

That simple behavior is most useful when the value side is already unique. If your hash contains repeated values, the method still works, but later keys can replace earlier ones with the same value. In practice, invert is best when you want a quick reverse lookup and you already know the data is one-to-one.

Description

The invert method creates a new collection by exchanging keys and values in the original map. The original map remains unchanged.

scores = { alice: 100, bob: 95, carol: 98 }
inverted = scores.invert
# => { 100 => :alice, 95 => :bob, 98 => :carol }

The original collection stays untouched, so you can still look up scores by name after creating the reverse lookup. This is a common pattern when building small indexes or lookup tables where the value side contains unique identifiers like IDs, codes, or labels.

behavior with duplicate values

If multiple keys map to the same value, invert causes data loss. When duplicate values exist, the last key in iteration order wins and overwrites previous entries.

inventory = { apples: 5, oranges: 5, bananas: 3 }
inverted = inventory.invert
# => { 5 => :oranges, 3 => :bananas }  # :apples dropped — both had value 5

This happens because the last key processed overwrites earlier ones with the same value. When you are reading or debugging a real hash, that means invert is safest for identifiers, codes, and labels that already behave like unique keys. If the values are more like categories, a grouped approach is easier to trust because it keeps every match instead of silently discarding some of them.

handling duplicate values

To invert a hash while preserving all entries when values are not unique, use each_with_object:

inventory = { apples: 5, oranges: 5, bananas: 3 }
inverted = inventory.each_with_object({}) { |(k, v), h| (h[v] ||= []) << k }
# => { 5 => [:apples, :oranges], 3 => [:bananas] }

This approach groups keys by their shared value into arrays. It is a better fit when you need to keep every original key and you want the reverse lookup to stay complete. The tradeoff is a little more memory use, but the result is clearer when duplicate values are part of the design rather than an accident.

Grouped results are often the better fit when you are building a lookup that needs to preserve every match. Plain invert is shorter, but the grouped version keeps the full picture intact.

Return Value

Always returns a new Hash instance. The original map is not modified.

original = { x: 1, y: 2 }
result = original.invert

original.object_id == result.object_id  # => false
original  # => { x: 1, y: 2 }
result    # => { 1 => :x, 2 => :y }

Because invert returns a fresh collection, you can chain more map work on top of it without touching the original object. That makes it a clean helper for one-off reversals and small indexes, and it keeps the original hash available if you need to compare results later.

See Also

  • Hash#keys — returns an array of all keys in the hash
  • Hash#values — returns an array of all values in the hash
  • Hash#merge — merges two hashes together