Как найти хэш-ключ, содержащий соответствующее значение
Учитывая, что у меня есть хеш ниже клиентов, есть ли быстрый рубиновый способ (без необходимости писать многострочный script), чтобы получить ключ, который я хочу сопоставить с client_id? Например. Как получить ключ для client_id == "2180"
?
clients = {
"yellow"=>{"client_id"=>"2178"},
"orange"=>{"client_id"=>"2180"},
"red"=>{"client_id"=>"2179"},
"blue"=>{"client_id"=>"2181"}
}
Ответы
Ответ 1
Вы можете использовать Enumerable # select:
clients.select{|key, hash| hash["client_id"] == "2180" }
#=> [["orange", {"client_id"=>"2180"}]]
Обратите внимание, что результатом будет массив всех совпадающих значений, каждый из которых является массивом ключа и значения.
Ответ 2
Ruby 1.9 и больше:
hash.key(value) => key
Ruby 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"})
Ответ 3
Вы можете инвертировать хэш. clients.invert["client_id"=>"2180"]
возвращает "orange"
Ответ 4
Вы можете использовать hashname.key(valuename)
Или инверсия может быть в порядке. new_hash = hashname.invert
предоставит вам new_hash
, который позволит вам делать что-то более традиционно.
Ответ 5
В соответствии с 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)
он вернет "конструктор".
Ответ 6
попробуйте следующее:
clients.find{|key,value| value["client_id"] == "2178"}.first
Ответ 7
Из документов:
- (Object?) обнаруживает (ifnone = nil) {| obj |...}
- (Object?) find (ifnone = nil) {| obj |...}
- (Object) detect (ifnone = nil)
- (Object) find (ifnone = nil)
Пропускает каждую запись в перечислении для блокировки. Возвращает первый, для которого блок не является ложным. Если объект не соответствует, вызывает ifnone и возвращает его результат, когда он указан, или возвращает иначе.
Если блок не указан, вместо него возвращается счетчик.
(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
Ответ 8
Другой подход, который я попробовал бы, это использовать #map
clients.map{ |key, _| key if clients[key] == {"client_id"=>"2180"} }.compact
#=> ["orange"]
Это вернет все вхождения заданного значения. Подчеркивание означает, что нам не нужно использовать значение ключа, чтобы оно не было привязано к переменной. Массив будет содержать nils, если значения не совпадают - поэтому я положил #compact
в конец.
Ответ 9
Лучший способ найти ключ для определенного значения - использовать ключевой метод, доступный для хеша....
gender = {"MALE" => 1, "FEMALE" => 2}
gender.key(1) #=> MALE
Я надеюсь, что он решает вашу проблему...
Ответ 10
Вот простой способ найти ключи заданного значения:
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")
он даст вам пару ключ-значение.