2011-01-14 10 views
23

मैं एक सरणी में प्रत्येक nth आइटम का चयन करने के लिए रूबी में एक रास्ता खोजने के लिए देख रहा हूँ। उदाहरण के लिए, हर दूसरे आइटम का चयन परिणत हो गया:आप सरणी में प्रत्येक nth आइटम का चयन कैसे करते हैं?

में
["cat", "dog", "mouse", "tiger"] 

:

["dog", "tiger"] 

वहाँ ऐसा करने के लिए एक रूबी विधि है, या वहाँ यह करने के लिए किसी भी अन्य तरीका है?

मैं की तरह कुछ उपयोग करने की कोशिश:

[1,2,3,4].select {|x| x % 2 == 0} 
# results in [2,4] 

लेकिन यह है कि केवल पूर्णांकों, नहीं तार के साथ एक सरणी के लिए काम करता है।

उत्तर

15

तुम भी कदम इस्तेमाल कर सकते हैं:

n = 2 
a = ["cat", "dog", "mouse", "tiger"] 
b = (n - 1).step(a.size - 1, n).map { |i| a[i] } 
+0

के रूप में लिख सकते हैं यह सही है। इतना साफ। बहुत बहुत धन्यवाद :) – sjsc

+1

धन्यवाद, कृपया ध्यान दें कि मैंने एक-एक-एक मुद्दा तय किया है कि 'n = 3' दिखाएगा। –

+1

'चरण' ने मुझे शुरुआत में समझ में नहीं आया क्योंकि मैंने पहले उस फॉर्म का उपयोग नहीं किया है। यह '(n-1 ... a.size) .step (n) .map {| i | के बराबर है एक [i]} ' – Matt

5

इस बारे में कैसे -

arr = ["cat", "dog", "mouse", "tiger"] 
n = 2 
(0... arr.length).select{ |x| x%n == n-1 }.map { |y| arr[y] } 
    #=> ["dog", "tiger"] 
+0

यह महान अंशुल काम करता है। धन्यवाद! – sjsc

4

आप अन्य स्थानों में, आप Enumerable के लिए एक विधि जोड़ सकते हैं की जरूरत है:

module Enumerable 
    def select_with_index 
     index = -1 
     (block_given? && self.class == Range || self.class == Array) ? select { |x| index += 1; yield(x, index) } : self 
    end 
end 

p ["cat", "dog", "mouse", "tiger"].select_with_index { |x, i| x if i % 2 != 0 } 

नोट: यह अपने मूल कोड नहीं है। मुझे here से मिला जब मुझे आपकी वही आवश्यकता थी।

+0

यह बहुत अच्छा है। धन्यवाद ज़ब्बा! – sjsc

+3

1.9 में आप इसे 'to_enum.with_index.select' –

+7

के रूप में लिख सकते हैं 1.9 में आप इसे' .select.with_index' – Nakilon

48

आप उपयोग कर सकते हैं Enumerable#each_slice:

["cat", "dog", "mouse", "tiger"].each_slice(2).map(&:last) 
# => ["dog", "tiger"] 

अद्यतन:

टिप्पणी में उल्लेख किया है, last, हमेशा उपयुक्त नहीं है तो यह कर सकता है first द्वारा प्रतिस्थापित किया जाना चाहिए, और पहले तत्व को छोड़ना:

["cat", "dog", "mouse", "tiger"].drop(1).each_slice(2).map(&:first) 

दुर्भाग्य से, इसे कम सुरुचिपूर्ण बनाते हैं।

IMO, सबसे खूबसूरत .select.with_index उपयोग करने के लिए है, जो Nakilon उसकी टिप्पणी में सुझाव दिया है:

["cat", "dog", "mouse", "tiger"].select.with_index{|_,i| (i+1) % 2 == 0} 
+1

ओह बकवास। यदि सरणी में तत्वों की विषम संख्या है, तो यह पिछले एक को भी वापस कर देगा। कोई बात नहीं, इसे एक विचार के रूप में यहां रहने दें ... –

+0

पॉइंटर Mladen और "each_slice" के लिए संसाधन के लिए बहुत बहुत धन्यवाद :) – sjsc

4

फिर भी एक और तरीके:

xs.each_with_index.map { |x, idx| x if idx % 2 != 0 }.compact 

xs.each_with_index.select { |x, idx| idx % 2 }.map(&:first) 

xs.values_at(*(1...xs.length).step(2)) 
4

आप बस values_at विधि का उपयोग कर सकते हैं। आप आसानी से documentation में पा सकते हैं।

यहाँ कुछ उदाहरण हैं:

array = ["Hello", 2, "apple", 3] 
array.values_at(0,1) # pass any number of arguments you like 
=> ["Hello", 2] 

array.values_at(0..3) # an argument can be a range 
=>["Hello", 2, "apple", 3] 

मेरा मानना ​​है कि यह "कुत्ता" और "टाइगर"

array = ["cat", "dog", "mouse", "tiger"] 
array.values_at(1,3) 

और अपने एक और सरणी के साथ साथ आपकी समस्या का समाधान होगा

[1,2,3,4].values_at(1,3) 
=> [2, 4] 
4

मुझे अंशुल और मुयू के दोनों जवाब पसंद हैं और प्रत्येक को एक बंदर के रूप में सबमिट करके उन्हें थोड़ा सा परिशोधित और सरल बनाना चाहते हैं Enumerable रहे हैं:

म्यू के

module Enumerable 
    def every_nth(n) 
    (n - 1).step(self.size - 1, n).map { |i| self[i] } 
    end 
end 

अंशुल के

module Enumerable 
    def every_nth(n) 
    (0... self.length).select{ |x| x%n == n-1 }.map { |y| self[y] } 
    end 
end 

तो यह साथ काम करने के बहुत आसान है। उदाहरण के लिए, पर विचार करें:

a = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25] 

a.every_nth(2) 
=> [2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24] 

a.every_nth(3) 
=> [3, 6, 9, 12, 15, 18, 21, 24] 

a.every_nth(5) 
=> [5, 10, 15, 20, 25] 
2

मैं एक बहुत ही आसान तरीका सुझाव देंगे:

animals.each_with_index.map { |_, i| i.odd? } 

उदा

['a','b','c','d'].select.with_index{ |_,i| i.odd? } 
=> ["b", "d"] 
संबंधित मुद्दे