रूबी में डुप्लिकेट कुंजियों को अधिलेखित किए बिना मैं दो हैश का विलय कैसे कर सकता हूं?


140

क्या डुप्लिकेट कुंजियों को अधिलेखित किए बिना दो हैश को मर्ज करने का एक आसान या सुरुचिपूर्ण तरीका है?

यही है, अगर कुंजी मूल हैश में मौजूद है तो मैं इसके मूल्य को बदलना नहीं चाहता हूं।


क्या आप वास्तव में सरणियों का अर्थ करते हैं (जैसे: ['ए', 'बी', 'सी']) या हैश (जैसे: {’ए’ => १, 2 बी ’= २, 'सी’ => ३}) ?
एलेक्स रीसनर

क्षमा करें, मैं हैश के बारे में बात कर रहा था :)
क्लाउडियो अकियारेसी

जवाबों:


232

आप दो हैश है, तो optionsऔर defaults, और आप मर्ज करना चाहते defaultsमें optionsमर्ज: मौजूदा कुंजी अधिलेखन के बिना, आप वास्तव में क्या करना चाहते हैं विपरीत है optionsमें defaults:

options = defaults.merge(options)

या, यदि आप रेल का उपयोग कर रहे हैं तो आप कर सकते हैं:

options.reverse_merge!(defaults)

पूरी तरह से सहमत हूँ, रिवर्स_मर्ज के लिए बहुत बहुत धन्यवाद! विधि यह नहीं जानती थी :)
क्लाउडियो अकियारेसी

क्यों यहाँ कोष्ठक की जरूरत है? आप बस डिफ़ॉल्ट नहीं कर सकते हैं। विकल्प दिखाई देता है।
डोनाटो

1
वे का बहिष्कार कर रहे हैं reverse_merge!5.1 रेल में सुरक्षा के मुद्दों की वजह से
MIRV - मैट

@ मीरव-मैट - मुझे मूल्यह्रास नोटिस नहीं दिखता है। apidock.com/rails/v6.0.0/Hash/reverse_merge%21
क्षितिज

17

मौजूदा मानों को अधिलेखित किए बिना हैश को मर्ज करने या हैश को पुन: सौंपने के लिए मानक रूबी पुस्तकालय में विलय करने का एक तरीका है।

important_hash.merge!(defaults) { |key, important, default| important }

3

यदि आपकी समस्या यह है कि मूल हैश और दूसरा दोनों में डुप्लिकेट कुंजियाँ हो सकती हैं और आप दोनों दिशाओं में ओवरराइटिंग नहीं करना चाहते हैं, तो आपको किसी प्रकार की टक्कर की जाँच और हैंडलिंग के साथ एक सरल मैनुअल मर्ज के लिए जाना पड़ सकता है:

hash2.each_key do |key|
  if ( hash1.has_key?(key) )
       hash1[ "hash2-originated-#{key}" ] = hash2[key]
  else
       hash1[key]=hash2[key]
  end
end

जाहिर है, यह बहुत ही अशिष्टता है और माना जाता है कि hash1 में "hash2-originated-जो भी" नामक कोई कुंजी नहीं है - आप कुंजी में एक नंबर जोड़ने से बेहतर हो सकते हैं इसलिए यह key1, key2 और इसलिए जब तक आप हिट नहीं करते हैं वह जो पहले से ही हैश 1 में नहीं है। इसके अलावा, मैंने कुछ महीनों तक कोई माणिक्य नहीं किया है, ताकि संभवतः वाक्यविन्यास सही न हो, लेकिन आपको जेंट प्राप्त करने में सक्षम होना चाहिए।

वैकल्पिक रूप से एक सरणी के रूप में कुंजी के मूल्य को फिर से परिभाषित करें ताकि hash1 [key] hash1 से मूल मान और hash2 से मान लौटाए। निर्भर करता है कि आप वास्तव में क्या चाहते हैं।


कैसे के बारे में अगर दोनों कुंजी नहीं रख रहे हैं, लेकिन एक ही कुंजी के मूल्यों को जोड़ रहे हैं?
टॉम केसी चिउ

1
@ TomK.C.Chiu बहुत कुछ परिस्थितियों पर निर्भर करेगा कि हम सवाल से न्याय नहीं कर सकते - क्या होगा अगर hash1 में मान तार हैं और hash2 पूर्णांक हैं? कुछ मामलों के लिए जो एक व्यवहार्य विकल्प हो सकता है, लेकिन अधिक बार यह समस्याओं का कारण होगा- मूल्यों के लिए सूचियों का उपयोग करने का सुझाव काफी सफाई से काम करता है।
ग्लेनट्रॉन


0

यदि आप दो हैश को मर्ज करना चाहते हैं optionsऔर defaultsडेस्टिनेशन हैश को ओवरराइट किए बिना, तो आप चेक कर सकते हैं selectकि डेस्टिनेशन हैश में पहले से मौजूद है या नहीं। यहाँ रेल के बिना शुद्ध रूबी समाधान है:

options  = { "a" => 100, "b" => 200 }
defaults = { "b" => 254, "c" => 300 }
options.merge!(defaults.select{ |k,_| not options.has_key? k })

# output
# => {"a"=>100, "b"=>200, "c"=>300}

या यदि कुंजी मौजूद है, लेकिन इसमें शामिल है nilऔर आप इसे अधिलेखित करना चाहते हैं:

options.merge!(defaults.select{ |k,_| options[k].nil? })
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.