2013-03-30 16 views
12

Ben, buRuby'de belirli bir adımla ters çevrilmiş bir aralıkta nasıl yineleyebilirim? ters aralık boş aralığa eşit olduğundan

(0..10).step(2){|v| puts v} 

gibi yineleme ancak, bu şekilde

(10..0).step(2){|v| puts v} 

o bana hiçbir şey kazanacağım yineleme olamaz. Tabii ki bu

10.downto(0){|v| puts v} 

gibi geriye yineleme ancak yöntemin downto beni varsayılan 1. Bu çok temel bir şey hariç diğer adımı ayarlamasına izin vermez bu yüzden bir yerleşik bir yolu olmalı herhalde Bunu bilmiyorum, yap.

+0

Eğer '(0..10) .step gibi bir şey yapabilirsiniz (2) .diyar ', ancak (10..0) .step (2)' den farklı olduğu varsayılan çıktıda bir mantık eklemeniz gerekebilir. – jvnill

+0

' (0..10) .step (2) .reverse' geçerli değil; Ruby diyor ki: 'NoMethodError: # Enumerator için tanımlanmamış yöntem 'reverse': 0..10: step (2)>'. –

cevap

20

Neden kullanmayın Numeric#step: Dokümanlar

:

Invokes block with the sequence of numbers starting at num, incremented by step (default 1) on each call. The loop finishes when the value to be passed to the block is greater than limit (if step is positive) or less than limit (if step is negative). If all the arguments are integers, the loop operates using an integer counter. If any of the arguments are floating point numbers, all are converted to floats, and the loop is executed floor(n + n*epsilon)+ 1 times, where n = (limit - num)/step. Otherwise, the loop starts at num, uses either the < or > operator to compare the counter against limit, and increments itself using the + operator.

 
irb(main):001:0> 10.step(0, -2) { |i| puts i } 
10 
8 
6 
4 
2 
0 
+1

Güzel. Ayrıca başka bir yol buldum, ancak daha az zarif: (-10.0.0) .step (2) {| v | -1 * v} koyar – user1887348

4

Gereksinim duymadığınız değerleri atlayarak step'u taklit etmeniz çok kolaydır. Böyle bir şey:

10.downto(0).each_with_index do |x, idx| 
    next if idx % 3 != 0 # every third element 
    puts x 
end 
# >> 10 
# >> 7 
# >> 4 
# >> 1 
+0

Eğer koşullu olarak her bir deyimde öğeleri atlıyorsanız, yanlış yapıyorsunuzdur ve şunu seçmelisiniz: '10.downto (0) .select.with_index {| x, idx | idx% 3 == 0} .each {| x | x} ' – SamStephens

+0

@SamStephens koyar: Bu tartışmalıdır. –

+0

Her şey, ancak Ruby'nin işlevsel koleksiyon temelli özelliklerini kullanacaksanız, bunların işlevsel ve zorlayıcı stilleri karıştırmak yerine tutarlı bir şekilde kullanmanız gerektiğini iddia edeceğim. – SamStephens