एक बार में दो सरणियों पर पुनरावृत्ति करने के लिए 'रूबी रास्ता' क्या है


127

एक समस्या को हल करने की तुलना में एक वाक्यविन्यास जिज्ञासा का अधिक ...

मेरे पास समान लंबाई के दो सरणियाँ हैं, और एक ही समय में उन दोनों पर पुनरावृति करना चाहते हैं - उदाहरण के लिए, एक निश्चित सूचकांक पर अपने दोनों मूल्यों का उत्पादन करने के लिए।

@budget = [ 100, 150, 25, 105 ]
@actual = [ 120, 100, 50, 100 ]

मुझे पता है कि मैं each_indexसरणियों में उपयोग और अनुक्रमण कर सकता हूं जैसे:

@budget.each_index do |i|
  puts @budget[i]
  puts @actual[i]
end

क्या यह बेहतर करने के लिए एक रूबी तरीका है? कुछ इस तरह ?

# Obviously doesn't achieve what I want it to - but is there something like this?
[@budget, @actual].each do |budget, actual|
  puts budget
  puts actual
end

1
दोनों समान आकार के सरणियाँ हैं?
अनुराग

1
हां - दोनों एक ही लंबाई के जाने जाते हैं
nfm

जवाबों:


276
>> @budget = [ 100, 150, 25, 105 ]
=> [100, 150, 25, 105]
>> @actual = [ 120, 100, 50, 100 ]
=> [120, 100, 50, 100]

>> @budget.zip @actual
=> [[100, 120], [150, 100], [25, 50], [105, 100]]

>> @budget.zip(@actual).each do |budget, actual|
?>   puts budget
>>   puts actual
>> end
100
120
150
100
25
50
105
100
=> [[100, 120], [150, 100], [25, 50], [105, 100]]

12
'.each' सरणी तत्वों को प्रकट कर सकता है? मुझे आश्चर्य है कि रूबी को मैं कितना नहीं जानता: /
निकिता रियाब

5
यदि आप इस तरह की अभिव्यक्ति का उपयोग करने जा रहे हैं, तो हमेशा कॉल के मामले में, कोष्ठक का उपयोग करना सबसे अच्छा है। @ budget.zip (@actual) .each
AboutRuby

1
@AboutRuby: इस मामले में, इसकी आवश्यकता है! फिक्स्ड।
मार्क-आंद्रे लाफ्यून

2
जब मुझे इस तरह से रूबी रेखाएँ दिखाई देती हैं, तो मैं अपने हाथों को हवा में फेंक देता हूँ और कमरे को एक चंपू की तरह घुमाता हूँ!
इब्बानम

9
क्या यह पैमाना है? अगर मेरे पास 2 10000 आइटम सरणियाँ हैं, तो क्या इसके लिए 20,000 आइटम सरणी बनाने की आवश्यकता है? डॉक्स यह सुझाव देते हैं।
टॉम एंडरसन

21

Array.zipविधि का उपयोग करें और क्रमिक रूप से संबंधित तत्वों पर पुनरावृति करने के लिए इसे एक ब्लॉक पास करें ।


20

प्रगणकों का उपयोग करते समय एक बार में दो सरणियों पर पुनरावृति करने का एक और तरीका है:

2.1.2 :003 > enum = [1,2,4].each
 => #<Enumerator: [1, 2, 4]:each> 
2.1.2 :004 > enum2 = [5,6,7].each
 => #<Enumerator: [5, 6, 7]:each> 
2.1.2 :005 > loop do
2.1.2 :006 >     a1,a2=enum.next,enum2.next
2.1.2 :007?>   puts "array 1 #{a1} array 2 #{a2}"
2.1.2 :008?>   end
array 1 1 array 2 5
array 1 2 array 2 6
array 1 4 array 2 7

Enumerators ऊपर उपयोग किए गए उदाहरणों की तुलना में अधिक शक्तिशाली हैं, क्योंकि वे अन्य तकनीकों के बीच अनंत श्रृंखला, समानांतर पुनरावृत्ति की अनुमति देते हैं।


1
क्या loopऊपर दिखाए गए के अंदर सूचकांक प्राप्त करने का एक तरीका है ?
बीजू

16

a.zip(b).each{|x,y| }जैसा कि दूसरों ने कहा है, इसके अलावा , आप यह भी कह सकते हैं [a,b].transpose.each{|x,y| }, जो मुझे एक छोटे से अधिक सममित के रूप में प्रभावित करता है। शायद उतना तेज नहीं है, हालांकि, जब से आप अतिरिक्त [a,b]सरणी बना रहे हैं ।


11
+1 के बारे में अच्छी चीजों में से transposeएक यह एक अपवाद है अगर दो सरणियों की लंबाई समान नहीं है।
एंड्रयू ग्रिम

14

मूल प्रश्न से संबंधित, असमान लंबाई की सरणियों पर पुनरावृत्ति के लिए, जहाँ आप चाहते हैं कि मान आपके आस-पास के चक्र का उपयोग कर सकें

[1,2,3,4,5,6].zip([7,8,9].cycle)

और रूबी तुम्हें दे देंगे

[[1, 7], [2, 8], [3, 9], [4, 7], [5, 8], [6, 9]]

यह आपको उन nilमूल्यों से बचाता है जो आपको सिर्फ ज़िप का उपयोग करने से मिलेंगे


6

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

enum1 = (1..5).cycle
enum2 = (10..12).cycle

enum1.zip(enum2)विफल रहता है क्योंकि zipसभी तत्वों का मूल्यांकन करने और उन्हें संयोजित करने का प्रयास करता है। इसके बजाय, यह करें:

enum1.lazy.zip(enum2)

यह एक lazyपरिणामी प्रगणक आलसी-मूल्यांकन करके आपको बचाता है।


2

कैसे के बारे में समझौता, और #each_with_index का उपयोग कर?

include Enumerable 

@budget = [ 100, 150, 25, 105 ]
@actual = [ 120, 100, 50, 100 ]

@budget.each_with_index { |val, i| puts val; puts @actual[i] }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.