रूबी में मर्ज और इंटरलेव दो एरेज़


106

मेरे पास निम्नलिखित कोड हैं:

a = ["Cat", "Dog", "Mouse"]
s = ["and", "&"]

मैं सरणी sको सरणी में विलय करना चाहता हूं aजो मुझे देगा:

["Cat", "and", "Dog", "&", "Mouse"]

रूबी ऐरे और एनुमरबल डॉक्स के माध्यम से देखते हुए, मुझे ऐसी कोई विधि नहीं दिखती जो इसे पूरा करेगी।

वहाँ एक तरीका है कि मैं यह प्रत्येक सरणी के माध्यम से पुनरावृत्ति के बिना कर सकता हूँ?


a में हमेशा 3 तत्व और दो होंगे? कुछ और उदाहरण उपयोगी होंगे।
टोकन

जवाबों:


171

आप ऐसा कर सकते हैं:

a.zip(s).flatten.compact

4
क्या होगा अगर a3 से अधिक तत्व हैं?
माइकल कोहल

116
["a", "b"] .concat (["c", "d"]) # => ["a", "b", "c", "d"]
Leo Romanovsky

30
@Leo, @chuck: यदि आप उदाहरण पढ़ें आप क्रिस करना चाहता है कि देखेंगे बिछा तत्वों, नहीं जोड़ उन्हें। अनिवार्य रूप से, वह यह चाहता है [a, s].transposeकि #zipस्पष्ट समाधान के रूप में छोड़कर, दो पंक्तियों के अनुरूप नहीं है । और मुझे विश्वास नहीं है कि वह वास्तव में परवाह करता aथा कि क्या उत्परिवर्तित था ... मुझे नहीं लगता कि वह एक उत्परिवर्ती बनाम कार्यात्मक समाधान पर टिप्पणी कर रहा था, वह सिर्फ पैटर्न का वर्णन करने की कोशिश कर रहा था।
डिजिटलरोस

15
+1 एकमात्र व्यक्ति होने के लिए जिसने वास्तव में ब्लममिन के प्रश्न को पढ़ा है! > _ <
मैट फ्लेचर

5
इससे भी महत्वपूर्ण बात यह है कि यदि दो सरणियाँ असमान लंबाई की हों तो क्या होगा? खासकर अगर s लंबा है? मुझे लगता है कि क्रिस जिस उदाहरण के साथ काम कर रहा है वह वास्तविक डेटा नहीं है, मैं इसे सुरक्षित रूप से मान सकता हूं। विचार करें: [] .zip [१, २] => नील (उस समय #flatten को कॉल करने के लिए एक कठिन समय जा रहा है) [३,४]। ज़िप ([१, ३, ५,)]] => [[३ , 1], [4, 3]] (उफ़, लगता है कि हम 2 के सरणी में अंतिम कुछ तत्वों की परवाह नहीं करते हैं)
hoff2

32

यह क्रिस के लिए पूछे गए क्रम में परिणाम सरणी नहीं देगा, लेकिन यदि परिणामी सरणी का क्रम मायने नहीं रखता है, तो आप बस उपयोग कर सकते हैं a |= b। यदि आप म्यूट नहीं करना चाहते हैं a, तो आप a | bपरिणाम को एक चर के लिए लिख और असाइन कर सकते हैं ।

Http://www.ruby-doc.org/core/classes/Array.html#M000275 पर ऐरे वर्ग के लिए सेट यूनियन प्रलेखन देखें ।

यह उत्तर मानता है कि आप डुप्लिकेट सरणी तत्वों को नहीं चाहते हैं। यदि आप अपने अंतिम सरणी में डुप्लिकेट तत्वों को अनुमति देना चाहते हैं, a += bतो यह ट्रिक करना चाहिए। फिर से, यदि आप परिवर्तन नहीं करना चाहते हैं a, a + bतो परिणाम को एक चर के लिए उपयोग करें और असाइन करें।

इस पृष्ठ पर कुछ टिप्पणियों के जवाब में, ये दोनों समाधान किसी भी आकार के सरणियों के साथ काम करेंगे।


यह निश्चित रूप से सबसे अच्छा लगता है।
अर्दवीस

11
यह ["Cat", "Dog", "Mouse", "and", "&"]वही देता है , जो ओपी नहीं चाहता था।
एंड्रयू ग्रिम

बहुत बढ़िया कॉल, एंड्रयू। मैं अपना उत्तर यह कहने के लिए अपडेट करूंगा कि मैंने क्रिस के प्रश्न का उत्तर नहीं दिया।
माइकल स्टॉकर

29

यदि आप डुप्लिकेट नहीं चाहते हैं, तो बस यूनियन ऑपरेटर का उपयोग क्यों न करें :

new_array = a | s

1
एक कम, सरल, सुरुचिपूर्ण समाधान के लिए +1 प्रदान करना।
जियाकोमो १

बेशक यह सवाल का जवाब देता है! सवाल था: "मैं सरणी को सरणी में विलय करना चाहता हूं"
डगलस

अच्छा समाधान - लेकिन इससे परिणामों का क्रम बदल जाता है। से परिणाम sनए सरणी के अंत में होंगे।
हेंड्रिक

1
तत्वों का क्रम वह नहीं होगा जो ओपी चाहता था, हालांकि।
22

6
s.inject(a, :<<)

s   #=> ["and", "&"]
a   #=> ["Cat", "Dog", "Mouse", "and", "&"]

यह आपको आपके द्वारा मांगे गए आदेश को नहीं देता है, लेकिन यह दो सरणियों को एक में जोड़कर विलय करने का एक अच्छा तरीका है।


मुझे यह पसंद है, छोटा और साफ। :)
नाफा बोउटफर

6

यहां एक समाधान है जो विभिन्न आकारों (सामान्य समाधान) के कई सरणियों को इंटरलेय करने की अनुमति देता है:

arr = [["Cat", "Dog", "Mouse", "boo", "zoo"],
 ["and", "&"],
 ["hello", "there", "you"]]

first, *rest = *arr; first.zip(*rest).flatten.compact
=> ["Cat", "and", "hello", "Dog", "&", "there", "Mouse", "you", "boo", "zoo"]

2
अच्छा! एक सीमा, पहली सरणी सबसे लंबी होनी चाहिए।
ब्रायन लो

@BrianLow शानदार कैच!
अब्दो

5

यह बिल्कुल सुरुचिपूर्ण नहीं है, लेकिन यह किसी भी आकार के सरणियों के लिए काम करता है:

>> a.map.with_index { |x, i| [x, i == a.size - 2 ? s.last : s.first] }.flatten[0..-2] 
#=> ["Cat", "and", "Dog", "&", "Mouse"]

अजीब किनारे के मामलों से निपटने के लिए +1, मुझे लगता है कि i = s.cycle; a.map { |x| [x, i.next] }.flatten[0..-2]हालांकि समान रूप से मान्य होगा।
म्यू

मुझे यकीन नहीं था कि यदि ओपी वैकल्पिक करना चाहता है andऔर &, इसलिए मैंने उसे aकिसी भी लम्बाई के लिए अनुमति देते हुए उसे सचमुच में ले लिया ।
माइकल कोहल

3

कैसे एक अधिक सामान्य समाधान के बारे में जो पहले सरणी सबसे लंबे समय तक काम नहीं करता है और किसी भी संख्या में सरणियों को स्वीकार करता है?

a = [
    ["and", "&"],
    ["Cat", "Dog", "Mouse"]
]

b = a.max_by(&:length)
a -= [b]
b.zip(*a).flatten.compact

 => ["Cat", "and", "Dog", "&", "Mouse"]

2

स्थिति है जहाँ दोनों को संभालने के लिए aऔर sएक ही आकार के नहीं हैं:

a.zip(s).flatten.compact | s
  • .compactसे बड़ा nilहोने पर निकाल देगाas
  • | sसे छोटी sहोने पर शेष वस्तुओं को जोड़ देगाas

1

इंटरलेव करने का एक तरीका और यह भी गारंटी देता है कि ज़िप विधि के लिए सबसे बड़ा सरणी कौन सा है, किसी सरणी nilको दूसरे सरणी आकार तक भरना है । इस तरह, आप यह भी गारंटी देते हैं कि कौन सा तत्व किस स्थिति में पहली स्थिति में होगा:

preferred_arr = ["Cat", "Dog", "Mouse"]
other_arr = ["and","&","are","great","friends"]

preferred_arr << nil while preferred_arr.length < other_arr.length
preferred_arr.zip(other_arr).flatten.compact
#=> ["Cat", "and", "Dog", "&", "Mouse", "are", "great", "friends"]

1
थोड़ा बेहतर: preferred_arr.zip(other_arr).flatten | other_arr(नील
बैकफिलिंग के

-2
arr = [0, 1]
arr + [2, 3, 4]

//outputs [0, 1, 2, 3, 4]

5
क्षमा करें ... आपको उस विशिष्ट आदेश पर ध्यान नहीं दिया गया जिसमें आप आउटपुट चाहते थे। मदद के लिए क्षमा याचना, फिर से नहीं होगा।
डेविड मॉरो
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.