Ruby Tuesday – Hash#invert

Today’s Ruby Tuesday is on Hash#invert.

Hash#invert will make the key the value, and the value the key, for each key-value pair in the hash.

{a: 1, b: 2, c: 3}.invert
# => {1=>:a, 2=>:b, 3=>:c}
{}.invert
# => {}
{twos: [2, 4, 6, 8], threes: [3, 6, 9], fives: [5, 10]}.invert
# => {[2, 4, 6, 8]=>:twos, [3, 6, 9]=>:threes, [5, 10]=>:fives}

This might seem like a odd thing to need, but sometimes your hash is not just a hash, but represents a bi-directional relationship.

One might use this when looking up DNA neucleobase pairings, where Adenine and Thymine always go together, and Guanine and Cytosine always pair togther, and we can create the full mapping by merging the mapping with it’s inverse.

{:A => :T, :C => :G}.invert
# => {:T=>:A, :G=>:C}
nucleobase_pairs.merge(nucleobase_pairs.invert)
# => {:A=>:T, :C=>:G, :T=>:A, :G=>:C}

Or when we have a mapping between a government id and a person (in the theoretically ideal world without identity theft), where we can get the person by their id, or the id for the person.

govt_ids_to_names = {123456789 => "Violetta",
                     999999999 => "Dilbert",
                     987654321 => "Nonnie Moose"}
# => {123456789=>"Violetta", 999999999=>"Dilbert", 987654321=>"Nonnie Moose"}
govt_ids_to_names.fetch(999999999)
# => "Dilbert"
govt_ids_to_names.invert.fetch("Nonnie Moose")
# => 987654321

And if we invert an inverted hash, we have the hash we started with.

govt_ids_to_names.invert.invert.fetch(123456789)
# => "Violetta"
govt_ids_to_names == govt_ids_to_names.invert.invert
# => true

–Proctor