일치하는 값이 포함 된 해시 키를 찾는 방법


198

아래에 클라이언트 해시가 있다고 가정하면 client_id와 일치 시키려면 주어진 키를 얻는 빠른 루비 방법이 있습니까 (여러 줄 스크립트를 작성하지 않아도 됨)? 예를 들어 열쇠를 얻는 방법 client_id == "2180"?

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

답변:


176

Enumerable # select 사용할 수 있습니다 :

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

결과는 일치하는 모든 값의 배열이며 각 값은 키와 값의 배열입니다.


22
차이 @Coderama findselectfind리턴 제와 매치 select(별칭으로한다 findAll) 모든 경기를 반환한다.
Daniel Vandersluis

필자는 이것이 둘 이상의 일치하는 인스턴스에 대해 더 안전한 옵션이라고 생각합니다.
Coderama

1
invert항목을 찾기 위해 완전히 새로운 해시를 작성하는 것 (을 호출하여 ) 보다 낫습니다 .
Hejazi

3
현재의 참고 루비 1.9.3 이이 경기에 새로운 해시를 반환합니다. Ruby <= 1.8.7에서 와 같이 배열을 반환하지 않습니다 . clients.select{|key, hash| hash["client_id"] == "2180" } # => {"orange"=>{"client_id"=>"2180"}}
AndrewS

열쇠를 얻으려면 간단히 다음과 같이 입력하십시오.clients.select{|key, hash| hash["client_id"] == "2180" }.keys
Mirror318

407

루비 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"})

2
해시에 여러 개의 키가있는 경우 전체 해시를에 제공해야하기 때문에 다소 혼란 스러울 수 index있습니다.
Daniel Vandersluis

51
Hash#index로 이름이 변경되는 Hash#key루비 1.9
Vikrant Chaudhary

12
동일한 값을 가진 여러 해시 쌍이있는 경우 첫 번째 일치 만 반환하고 일치하는 값을 가진 첫 번째 키를 반환합니다.
Mike Campbell

47

해시를 뒤집을 수 있습니다. clients.invert["client_id"=>"2180"]보고"orange"


3
이것은 또한 (짧기 때문에) 영리한 방법처럼 보입니다!
Coderama

이것은 역 해시를 생성하는 양식 배열 (선택 상자)에 필요한 것입니다.
Joseph Le Brech

22

hashname.key (valuename)를 사용할 수 있습니다

또는 역순 일 수도 있습니다. new_hash = hashname.invert당신에게 줄 것이다 new_hash당신이 더 많은 전통적으로 일을 할 수 있다는 것입니다.


3
Ruby의 최신 버전 (1.9 이상)에서이를 수행하는 올바른 방법입니다.
Lars Haugseth

#invert이 경우에는 키를 찾기 위해 버리기 해시 객체에 메모리를 할당하기 때문에이 방법은 정말 나쁜 생각입니다. 해시 크기에 따라 성능에 심각한 영향을 미칩니다
Dr.Strangelove

15

이 시도:

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

4
nil에서 .first를 호출 할 수 없으므로 find가 nil을 반환하면 예외가 발생합니다.
Schrockwell

1
Rails를 사용 .try(:first)하는 .first경우 예외를 피하기 위해 대신 사용할 수 있습니다 (예상치가 없을 것으로 예상되는 경우).
aaron-coding

2
Ruby 2.3.0 +당신이 사용할 수있는 안전한 네비게이터를 &.first 무기 호 예외 방지하기 위해 블록의 끝에서
가갠 가미에게


6

문서에서 :

  • (Object?) detect (ifnone = nil) {| obj | ...}
  • (개체?) find (ifnone = nil) {| obj | ...}
  • (객체) 감지 (ifnone = nil)
  • (객체) find (ifnone = nil)

열거 형의 각 항목을 블록으로 전달합니다. 블록이 거짓이 아닌 첫 번째를 반환합니다. 일치하는 객체가 없으면 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


3

특정 값의 키를 찾는 가장 좋은 방법은 해시에서 사용할 수있는 키 방법을 사용하는 것입니다.

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

문제가 해결되기를 바랍니다.


2

내가 시도하는 또 다른 접근법은 #map

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

주어진 값의 모든 발생을 반환합니다. 밑줄은 변수에 할당되지 않도록 키 값을 가져올 필요가 없음을 의미합니다. 값이 일치하지 않으면 배열에 nil이 포함 #compact되므로 끝 부분에 넣 습니다.


1

주어진 값의 키를 찾는 쉬운 방법은 다음과 같습니다.

    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") 

키-값 쌍을 제공합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.