2011-12-20 11 views
5

मुझे तर्क को समझने में कठिनाई हो रही है, मुझे हैश के दो एरे मर्ज करने की आवश्यकता होगी, ऐसा लगता है कि मैंने टी his question a while back से अलग तरीके से पूछा है, मैंने कुछ अन्य चीजों को भी उत्तर देने की कोशिश की है यहां पेश किया गया: merging arrays of hashesरेल हैंश के दो सरणी विलय?

यह समझने में कोई भी मदद मेरी मददगार होगी।

मैं निम्नलिखित सरणी है कहो, और इस विधि से ही उत्पादन होता है, ताकि आप उन :timestamp रों कल्पना Time वस्तुओं

[ 
    {:timestamp=>2011-12-19 00:00:00 UTC}, 
    {:timestamp=>2011-12-19 01:00:00 UTC}, 
    {:timestamp=>2011-12-19 02:00:00 UTC}, 
    {:timestamp=>2011-12-19 03:00:00 UTC}, 
    {:timestamp=>2011-12-19 04:00:00 UTC}, 
    {:timestamp=>2011-12-19 05:00:00 UTC} 
] 

और फिर इस तरह एक अतिरिक्त सरणी, जिनमें से प्रत्येक है होना करने के लिए कर सकते हैं एक और मूल्य (लेकिन कभी कभी :count के अलावा एक गुच्छा अधिक मान हो सकता है)

[ 
    {:timestamp=>2011-12-19 02:00:00 UTC, :count=>5}, 
    {:timestamp=>2011-12-19 04:00:00 UTC, :count=>21} 
] 

और कुछ इस तरह का परिणाम:

[ 
    {:timestamp=>2011-12-19 00:00:00 UTC}, 
    {:timestamp=>2011-12-19 01:00:00 UTC}, 
    {:timestamp=>2011-12-19 02:00:00 UTC, :count=>5}, 
    {:timestamp=>2011-12-19 03:00:00 UTC}, 
    {:timestamp=>2011-12-19 04:00:00 UTC, :count=>21}, 
    {:timestamp=>2011-12-19 05:00:00 UTC} 
] 

फिर, आपकी मदद के लिए धन्यवाद, मुझे यकीन नहीं है कि मैं इसके लिए उचित डिजाइन पैटर्न क्यों नहीं समझ सकता।

उत्तर

23

यह आप की तरह टाइमस्टैम्प द्वारा पहले समूह लग रहा है और उसके बाद मान विलय: यदि आप अपने "कुंजी" के रूप में प्रत्येक हैश के :timestamp विशेषता का उपयोग कर रहे हैं के बाद से

(a1+a2).group_by{|h| h[:timestamp]}.map{|k,v| v.reduce(:merge)} 
+1

आप कम कोड के लिए पिछले खंड पर निकाल सकते हैं 'और': 'v.reduce (: मर्ज)'। – htanata

+0

यह। अच्छा काम :) – d11wtq

+0

@htanata - हाँ आप सही हैं, मैंने अपडेट किया। – pguardiario

2
a = [ 
    {:timestamp=>'2011-12-19 00:00:00 UTC'}, 
    {:timestamp=>'2011-12-19 01:00:00 UTC'}, 
    {:timestamp=>'2011-12-19 02:00:00 UTC'}, 
    {:timestamp=>'2011-12-19 03:00:00 UTC'}, 
    {:timestamp=>'2011-12-19 04:00:00 UTC'}, 
    {:timestamp=>'2011-12-19 05:00:00 UTC'} 
] 

b = [ 
    {:timestamp=>'2011-12-19 02:00:00 UTC', :count=>5}, 
    {:timestamp=>'2011-12-19 04:00:00 UTC', :count=>21} 
] 

result = a.inject([]) do |memo, v| 
    if match = b.detect { |w| (w.to_a & v.to_a).any? } 
    memo << match.merge(v) 
    else 
    memo << v 
    end 
end 

p result 
2

, यह आसान है अगर आप वास्तव में कुंजी के रूप में :timestamp संपत्ति के साथ हैश में सरणियों कन्वर्ट:

h1 = Hash[a1.map{|h| [h[:timestamp], h]}] 
h2 = Hash[a2.map{|h| [h[:timestamp], h]}] 

उसके बाद, आप क्या चाहते हैं बस merge -ing को कम कर देता है दो हैश (और चाबी है कि जोड़ा गया था के साथ भाग रही):

p h1.merge(h2).values 
# => [ 
# {:timestamp=>"2011-12-19 00:00:00 UTC"}, 
# {:timestamp=>"2011-12-19 01:00:00 UTC"}, 
# {:timestamp=>"2011-12-19 02:00:00 UTC", :count=>5}, 
# {:timestamp=>"2011-12-19 03:00:00 UTC"}, 
# {:timestamp=>"2011-12-19 04:00:00 UTC", :count=>21}, 
# {:timestamp=>"2011-12-19 05:00:00 UTC"} 
#] 
संबंधित मुद्दे