2011-01-28 17 views
12

मैं दो हैंशों को कैसे विलय कर सकता हूं जिसके परिणामस्वरूप कोई नई कुंजी नहीं है, जिसका अर्थ है कि विलय दोनों हैंश में मौजूद कुंजी को मर्ज करेगा?कोई नई कुंजियों के साथ दो हैंश मर्ज कैसे करें

h = {:foo => "bar"} 
j = {:foo => "baz", :extra => "value"} 

puts h.merge(j) # {:foo => "baz"} 

मैं अपने वर्तमान कार्यान्वयन के रूप में ऐसा करने का एक बहुत साफ रास्ता तलाश कर रहा हूँ बहुत गंदा है:

उदाहरण के लिए, मैं निम्नलिखित चाहते हैं।

+0

यह एक हैश चौराहे की तरह है। आप विभिन्न मूल्यों के साथ कुंजी/मूल्य जोड़े के साथ क्या करना चाहते हैं? उदाहरण के लिए: एच = {: foo => "value1"}; जे = {: foo => "value2",: अतिरिक्त => "मान"} –

+0

@ रॉन गीजमैन - मैं बस उन्हें बाहर फेंकना चाहता हूं। लेकिन आपने मेरी रुचि बढ़ा दी है। क्या कुछ हैश/संख्यात्मक विधि है जो दो हैश (एक डुप्लिकेट कुंजी के साथ और दूसरा बचे हुए) के साथ लौटाएगी? – elmt

+0

नहीं, लेकिन DigitalRoss के उत्तर के आधार पर कुछ उपयोग करना आसान है। बस दो अलग-अलग हैंशों में सहेजें- एक मैचों के लिए और एक गैर-मैचों के लिए। –

उत्तर

14

आप कुंजी है कि दूसरी हैश से पहले हैश में नहीं थे हटाने सकता है, तो विलय:

h.merge j.select { |k| h.keys.include? k } 

विपरीत मेरी संपादित बाहर विकल्प, यह सुरक्षित है यदि आप एक merge! करने के लिए इसे बदलने का फैसला या update

+0

(मेरे डाउनवोट को हटा दिया गया, और इसे एक अपवोट में बदल दिया। मुझे 'विलय' के बारे में उलझन में मिला) –

+0

यह मेरी मशीन पर चेतावनी देता है- हैश। चयन दो तर्कों (| के, वी |) के साथ एक ब्लॉक में लेता है। –

+1

ओह, ओह, मैं रूबी 1.9 लिखता हूं। –

7

Yjerem का उत्तर रुबी 1.9 में काम करता है, लेकिन 1.8.x में नहीं। 1.8.x में Hash#select विधि एक सरणी देता है। Hash#reject एक हैश देता है।

h.reject { |k,v| !j.keys.include? k } 

आप केवल कुंजी-मान जोड़ों समान मूल्यों है कि रखना चाहते हैं, तो आप ऐसा कर सकते हैं:

h.reject { |k,v| j[k] != h[k] } 

बढ़त मामले निल्स है। आप अपने हैश में निल्स भंडारण कर रहे हैं तो आप ऐसा करने के लिए है:

h.reject { |k,v| !j.has_key? k or j[k] != h[k] } 
+0

आपके 1.8 समाधान रॉन गीजमैन के लिए धन्यवाद। – elmt

+0

हां। यह 1.9 के साथ भी संगत है। –

0
[h].inject({}) { |m,e| e.merge(j) { |k,o,n| m[k] = n }; m} 

या

[{}].inject(h) { |m,e| m.merge(j) { |k,o,n| e[k] = n }; e} 

या (शायद सबसे अच्छा है, लेकिन तकनीकी रूप से एक भी अभिव्यक्ति) ...

t = {}; h.merge(j) { |k,o,n| t[k] = n }; t 
8

यदि आप कार्य का उपयोग कर रहे हैं ivesupport (रेल का हिस्सा), आप Hash पर 2 अतिरिक्त तरीकों का लाभ ले सकते:

  • Hash#slice बस कुंजियां के लिए कहा साथ अलग-अलग तर्कों के रूप में वांछित कुंजी (नहीं चाबियों का एक सरणी) लेता है और एक नया हैश रिटर्न के लिये।
  • Hash#exceptslice के समान तर्क लेता है, लेकिन तर्कों में नहीं होने वाली कुंजी के साथ एक नया हैश देता है।

पहले लोड activesupport:

require 'active_support/core_ext' 

मर्ज केवल जिसका कुंजी h में पहले से ही j से प्रविष्टियां (अर्थातसंशोधित, लेकिन h में किसी भी जोड़ सकते हैं या नहीं निकालते हैं प्रविष्टियों):

h.merge(j.slice(*h.keys)) 

उदाहरण:

j.except(*h.keys) 

:

ignore_new = ->(h, j) { h.merge(j.slice(* h.keys)) } 
ignore_new.({a: 1, b: 2, c: 3}, {b: 10, c: 11, d: 12}) 
# => {:a=>1, :b=>10, :c=>11} 

j से बचा कि h में नहीं थे जाओ बोनस:

आप सच्चे चौराहे चाहते हैं, जिसका अर्थ है आप एक परिणाम केवल कुंजी है कि 2 हैश के बीच आम में हैं कि चाहते हैं, ऐसा करते हैं:

h.merge(j).slice(* (h.keys & j.keys)) 

उदाहरण: h से

intersect = ->(h, j) { h.merge(j).slice(* (h.keys & j.keys)) } 
intersect.({a: 1, b: 2, c: 3}, {b: 10, c: 11, d: 12}) 
# => {:b=>10, :c=>11} 

और बचा हुआ है कि नहीं थे j में 'टी:

h.except(*j.keys) 

अगर आपको स्ट्रिंगचाहते activesupport के HashWithIndifferentAccess उपयोग कर सकते हैंप्रतीकात्मक कुंजी-पहुंच समकक्ष समझा जा सकता है।

ध्यान दें कि उपर्युक्त उदाहरणों में से कोई भी मूल हैश बदलता नहीं है; इसके बजाय नए हैंश वापस कर दिए जाते हैं।

-1

ऐसा करने का अधिक अनुकूलित तरीका है:

h = {"foo"=> "bar"} 

j = {"foo" => "baz", "extra" => "value"} 


k = h.merge(j) 
result: {"foo"=>"baz", "extra"=>"value"} 

यहाँ कुंजी "foo" दूसरा हैश में "foo" पहले hash.But में अधिभावी है आप पुराने मूल्य यानी रखना चाहते हैं बार या यदि आप नया मान यानी "बाज़" रखना चाहते हैं? आप ऐसा कुछ कर सकते हैं:

k = h.merge(j){|key, old, new| old} 
result: {"foo"=>"bar", "extra"=>"value"} 


k = h.merge(j){|key, old, new| new} 

result: {"foo"=>"baz", "extra"=>"value"} 
+0

सवाल चाबियों के एक छेड़छाड़ के लिए पूछता है। नतीजा होना चाहिए {: foo => "baz"}, {"foo" => "baz", "अतिरिक्त" => "मान"} नहीं होना चाहिए – AndrewKS

संबंधित मुद्दे