How to find a hash key containing a matching value

Ruby

Ruby Problem Overview


Given I have the below clients hash, is there a quick ruby way (without having to write a multi-line script) to obtain the key given I want to match the client_id? E.g. How to get the key for client_id == "2180"?

clients = {
  "yellow"=>{"client_id"=>"2178"}, 
  "orange"=>{"client_id"=>"2180"}, 
  "red"=>{"client_id"=>"2179"}, 
  "blue"=>{"client_id"=>"2181"}
}

Ruby Solutions


Solution 1 - Ruby

Ruby 1.9 and greater:

hash.key(value) => key

Ruby 1.8:

You could use hash.index

> hsh.index(value) => key
> > Returns the key for a given value. If > not found, returns nil.
> > h = { "a" => 100, "b" => 200 }
> h.index(200) #=> "b"
> h.index(999) #=> nil

So to get "orange", you could just use:

clients.key({"client_id" => "2180"})

Solution 2 - Ruby

You could use Enumerable#select:

clients.select{|key, hash| hash["client_id"] == "2180" }
#=> [["orange", {"client_id"=>"2180"}]]

Note that the result will be an array of all the matching values, where each is an array of the key and value.

Solution 3 - Ruby

You can invert the hash. clients.invert["client_id"=>"2180"] returns "orange"

Solution 4 - Ruby

You could use hashname.key(valuename)

Or, an inversion may be in order. new_hash = hashname.invert will give you a new_hash that lets you do things more traditionally.

Solution 5 - Ruby

try this:

clients.find{|key,value| value["client_id"] == "2178"}.first

Solution 6 - Ruby

According to ruby doc http://www.ruby-doc.org/core-1.9.3/Hash.html#method-i-key key(value) is the method to find the key on the base of value.

ROLE = {"customer" => 1, "designer" => 2, "admin" => 100}
ROLE.key(2)

it will return the "designer".

Solution 7 - Ruby

From the docs:

  • (Object?) detect(ifnone = nil) {|obj| ... }
  • (Object?) find(ifnone = nil) {|obj| ... }
  • (Object) detect(ifnone = nil)
  • (Object) find(ifnone = nil)

Passes each entry in enum to block. Returns the first for which block is not false. If no object matches, calls ifnone and returns its result when it is specified, or returns nil otherwise.

If no block is given, an enumerator is returned instead.

(1..10).detect  {|i| i % 5 == 0 and i % 7 == 0 }   #=> nil
(1..100).detect {|i| i % 5 == 0 and i % 7 == 0 }   #=> 35

This worked for me:

clients.detect{|client| client.last['client_id'] == '2180' } #=> ["orange", {"client_id"=>"2180"}] 
    
clients.detect{|client| client.last['client_id'] == '999999' } #=> nil 

See: http://rubydoc.info/stdlib/core/1.9.2/Enumerable#find-instance_method

Solution 8 - Ruby

The best way to find the key for a particular value is to use key method that is available for a hash....

gender = {"MALE" => 1, "FEMALE" => 2}
gender.key(1) #=> MALE

I hope it solves your problem...

Solution 9 - Ruby

Another approach I would try is by using #map

clients.map{ |key, _| key if clients[key] == {"client_id"=>"2180"} }.compact 
#=> ["orange"]

This will return all occurences of given value. The underscore means that we don't need key's value to be carried around so that way it's not being assigned to a variable. The array will contain nils if the values doesn't match - that's why I put #compact at the end.

Solution 10 - Ruby

Heres an easy way to do find the keys of a given value:

    clients = {
      "yellow"=>{"client_id"=>"2178"}, 
      "orange"=>{"client_id"=>"2180"}, 
      "red"=>{"client_id"=>"2179"}, 
      "blue"=>{"client_id"=>"2181"}
    }

    p clients.rassoc("client_id"=>"2180")

...and to find the value of a given key:

    p clients.assoc("orange") 

it will give you the key-value pair.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionCoderamaView Question on Stackoverflow
Solution 1 - RubyAillynView Answer on Stackoverflow
Solution 2 - RubyDaniel VandersluisView Answer on Stackoverflow
Solution 3 - RubyPeter DeWeeseView Answer on Stackoverflow
Solution 4 - Rubyboulder_rubyView Answer on Stackoverflow
Solution 5 - RubyiNecasView Answer on Stackoverflow
Solution 6 - RubyAfzal MasoodView Answer on Stackoverflow
Solution 7 - RubyRimianView Answer on Stackoverflow
Solution 8 - RubyAditya KapoorView Answer on Stackoverflow
Solution 9 - RubyJaredView Answer on Stackoverflow
Solution 10 - RubySaleh RastaniView Answer on Stackoverflow