Find a Ruby hash key by value

Find a Ruby hash key by value

Let’s take a very simple Ruby hash with some US state abbreviations to their names

us_states = {
  'AK' => 'Alaska',
  'AL' => 'Alabama',
  'AR' => 'Arkansas',
  'AZ' => 'Arizona',
  'CA' => 'California',
  'CO' => 'Colorado',
  'CT' => 'Connecticut'
}

To retrieve the state name by its abbreviation, we would do:

us_states.key("California")
# CA
us_states.key("Arizona")
# AZ
us_states.key("Maine")
# nil

The last value will be nil because we do not have Maine in our has of states.

Now, what happens if we have multiple keys mapping to the same value? This is where we run into problems. Ruby will grab the first match and will not warn us that there are multiple keys.

Here is an example:

status_to_boostrap_label = {
  'active' => 'label-success',
  'pending' => 'label-info',
  'archived' => 'label-info',
  'inactive' => 'label-info',
  'invalid' => 'label-danger'
}
status_to_boostrap_label.key('label-info')
# pending

We should always be aware of this limitation when use this method.

We can always be precautious and add a check for the number of unique keys vs the number of unique values.

unless status_to_boostrap_label.values.uniq.size == status_to_boostrap_label.keys.uniq.size
  status_to_boostrap_label.key(value)
end