मिलान मूल्य वाले हैश कुंजी को कैसे खोजें


198

यह देखते हुए कि मेरे पास नीचे के ग्राहक हैश हैं, क्या मुझे क्लाइंट_आईडी से मेल खाने के लिए दी गई कुंजी प्राप्त करने के लिए एक त्वरित रूबी तरीका है (एक बहु-पंक्ति स्क्रिप्ट लिखने के बिना)? उदाहरण के लिए कुंजी कैसे प्राप्त करें 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 findऔर selectवह यह है कि findरिटर्न पहला मैच और select(जिसके द्वारा एलियास किया गया findAll) सभी मैचों देता है।
डैनियल वांडर्सलुइस

मैं देख रहा हूं, इसलिए यह उदाहरणों के लिए सुरक्षित विकल्प होगा जहां एक से अधिक मैच हैं।
कोडरमा

1
यह invertकेवल एक आइटम खोजने के लिए (कॉल करके ) एक नया हैश बनाने से बेहतर है ।
हिजाज़ी

3
ध्यान दें कि रूबी 1.9.3 के रूप में , यह मैचों के साथ एक नया हैश लौटाएगा। यह एक सरणी नहीं लौटाएगा, जैसा कि रूबी <= 1.8.7 में इस्तेमाल किया गया थाclients.select{|key, hash| hash["client_id"] == "2180" } # => {"orange"=>{"client_id"=>"2180"}}
एंड्रयूज

कुंजी प्राप्त करने के लिए, बस clients.select{|key, hash| hash["client_id"] == "2180" }.keys
डालिए

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
डैनियल वांडर्सलुइस

51
Hash#indexHash#keyरूबी 1.9 में बदल दिया गया है
विक्रांत चौधरी

12
ध्यान दें कि यह केवल पहला मैच लौटाता है, अगर एक ही मूल्य के साथ कई हैश जोड़ी हैं, तो यह एक मिलान मूल्य के साथ पहली कुंजी लौटाएगा।
माइक कैंपबेल

47

आप हैश उल्टा कर सकते हैं। clients.invert["client_id"=>"2180"]रिटर्न"orange"


3
यह भी एक चतुर तरीका लगता है (क्योंकि यह छोटा है) इसे करने के लिए!
कोडरमा

यह वही है जो मुझे फॉर्म ऐरे (चुनिंदा बक्सों के लिए) के लिए चाहिए जो बैकवर्ड हैश बनाते हैं
जोसेफ ले ब्रेच

22

आप hashname.key (क़ीमती नाम) का उपयोग कर सकते हैं

या, एक उलटा क्रम में हो सकता है। new_hash = hashname.invertआपको वह देगा जो आपको new_hashपारंपरिक रूप से चीजों को करने देता है।


3
रूबी के हालिया संस्करणों (1.9+) में यह करने का उचित तरीका है।
लार्स हग्सथ

#invertइस मामले में वास्तव में एक बुरा विचार है, क्योंकि आप अनिवार्य रूप से केवल एक कुंजी खोजने के लिए थ्रो-दूर हैश ऑब्जेक्ट के लिए मेमोरी आवंटित कर रहे हैं। हैश आकार के आधार पर इसका गंभीर प्रदर्शन प्रभाव होता है
Dr.Strangelove

15

इसे इस्तेमाल करे:

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

4
अगर कोई रिटर्न शून्य है तो यह अपवाद को फेंक देगा, क्योंकि आप कॉल नहीं कर सकते।
स्क्रोलवेल

1
यदि रेल का उपयोग आप अपवादों से बचने के .try(:first)बजाय कर सकते हैं .first(यदि आप उम्मीद कर रहे हैं कि मूल्य गायब होने के लिए संभव हो सकता है)।
एरन-कोडिंग

2
में Ruby 2.3.0 +आप उपयोग कर सकते हैं सुरक्षित नाविक &.first शून्य अपवाद से रोकने के लिए ब्लॉक के अंत में
गगन गामी


6

डॉक्स से:

  • (वस्तु?) का पता लगाने (ifnone = nil) {| obj | ...}
  • (वस्तु?) खोजें (ifnone = nil) {| obj | ...}
  • (वस्तु) का पता लगाना (ifnone = nil)
  • (ऑब्जेक्ट) खोजें (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


3

किसी विशेष मान के लिए कुंजी खोजने का सबसे अच्छा तरीका है कुंजी पद्धति का उपयोग करना जो हैश के लिए उपलब्ध है ...।

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

मुझे आशा है कि यह आपकी समस्या को हल करता है ...


2

एक और दृष्टिकोण जो मैं कोशिश करूंगा वह है उपयोग करके #map

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

यह दिए गए मूल्य की सभी घटनाओं को लौटा देगा। अंडरस्कोर का मतलब है कि हमें कुंजी के मूल्य की आवश्यकता नहीं है, इस तरह से इसे चारों ओर ले जाया जाए ताकि इसे एक चर को नहीं सौंपा जा सके। यदि मान मेल नहीं खाते हैं, तो सरणी में nils होंगे - यही कारण है कि मैं #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") 

यह आपको कुंजी-मूल्य जोड़ी देगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.