Как найти ключ хеша, содержащий соответствующее значение - PullRequest
186 голосов
/ 25 сентября 2010

Учитывая, что у меня есть клиентов хеш, есть ли быстрый способ ruby ​​(без необходимости написания многострочного скрипта), чтобы получить ключ, который я хочу соответствовать client_id? Например. Как получить ключ на client_id == "2180"?

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

Ответы [ 10 ]

388 голосов
/ 25 сентября 2010

Рубин 1,9 и выше:

hash.key(value) => key

Рубин 1,8 :

Вы можете использовать hash.index

hsh.index(value) => key

Возвращает ключ для заданного значения.Если не найдено, возвращает nil.

h = { "a" => 100, "b" => 200 }
h.index(200) #=> "b"
h.index(999) #=> nil

Таким образом, чтобы получить "orange", вы можете просто использовать:

clients.key({"client_id" => "2180"})
166 голосов
/ 25 сентября 2010

Вы можете использовать Enumerable # select :

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

Обратите внимание, что результатом будет массив всех совпадающих значений, где каждое является массивом ключа и значения.

46 голосов
/ 25 сентября 2010

Вы можете инвертировать хеш.clients.invert["client_id"=>"2180"] возвращает "orange"

21 голосов
/ 14 июня 2012

Вы можете использовать hashname.key (valuename)

Или инверсия может быть в порядке.new_hash = hashname.invert даст вам new_hash, что позволит вам делать вещи более традиционно.

12 голосов
/ 25 сентября 2010

попробуйте это:

clients.find{|key,value| value["client_id"] == "2178"}.first
11 голосов
/ 02 мая 2013

Согласно ruby ​​doc http://www.ruby -doc.org / core-1.9.3 / Hash.html # method-i-key ключ (значение) - это метод поиска ключа на базезначения.

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

вернет «конструктор».

5 голосов
/ 25 апреля 2013

Из документов:

  • (объект?) Обнаружение (ifnone = nil) {| obj | ...}
  • (Object?) Find (ifnone = nil) {| obj | ...}
  • (объект) обнаружение (ifnone = ноль)
  • (Объект) найти (ifnone = nil)

Передает каждую запись в enum для блокировки. Возвращает первое, для которого блок не является ложным. Если ни один объект не соответствует, вызывает ifnone и возвращает его результат, когда он указан, или возвращает nil в противном случае.

Если блок не указан, вместо него возвращается перечислитель.

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

Это сработало для меня:

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

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

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

2 голосов
/ 29 апреля 2013

Лучший способ найти ключ для определенного значения - использовать метод ключа, который доступен для хэша ....

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

Надеюсь, это решит вашу проблему ...

1 голос
/ 13 марта 2014

Другой подход, который я бы попробовал, это использовать #map

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

Это вернет все вхождения заданного значения. Подчеркивание означает, что нам не нужно переносить значение ключа, чтобы его нельзя было присвоить переменной. Массив будет содержать нули, если значения не совпадают - поэтому я поставил #compact в конце.

0 голосов
/ 09 августа 2014

Вот простой способ найти ключи заданного значения:

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

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

... и найти значение заданного ключа:

    p clients.assoc("orange") 

это будетдать вам пару ключ-значение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...