views:

40

answers:

4

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"}
}
+2  A: 

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.

Daniel Vandersluis
This works too!
Coderama
@Coderama The difference between `find` and `select` is that `find` returns the first match and `select` (which is aliased by `findAll`) returns all matches.
Daniel Vandersluis
I see, so this would be the safer option for instances where there is more than one match.
Coderama
+1  A: 

try this:

clients.find{|key,value| value["client_id"] == "2178"}.first
iNecas
This worked great
Coderama
A: 

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.index({"client_id" => "2180"})
Aillyn
I get nil when I run this...
Coderama
@Coderama I don't: http://codepad.org/2JpX9ei5
Aillyn
This would get kind of messy if the hashes had multiple keys, because you'd need to give the entire hash to `index`.
Daniel Vandersluis
+1  A: 

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

Peter DeWeese
This also seems like a clever way (because it's short) to do it!
Coderama