views:

120

answers:

2

UPDATE 2: For posterity, this is how I've settled on doing it (thanks to Jorg's input):

100.step(2, -2) do |x|
    # my code
end

(Obviously there are plenty of ways to do this; but it sounds like this is the most "Ruby" way to do it; and that's exactly what I was after.)


UPDATE: OK, so what I was looking for was step:

(2..100).step(2) do |x|
    # my code
end

But it turns out that I wasn't 100% forthcoming in my original question. I actually want to iterate over this range backwards. To my surprise, a negative step isn't legal.

(100..2).step(-2) do |x|
    # ArgumentError: step can't be negative
end

So: how do I do this backwards?


Hey guys, I'm completely new to Ruby, so be gentle.

Say I want to iterate over the range of even numbers from 2 to 100; how would I do that?

Obviously I could do:

(2..100).each do |x|
    if x % 2 == 0
        # my code
    end
end

But, obviously (again), that would be pretty stupid.

I know I could do something like:

i = 2
while i <= 100
    # my code
    i += 2
end

I believe I could also write my own custom class that provides its own each method (?). I am almost sure that would be overkill, though.

I'm interested in two things:

  1. Is it possible to do this with some variation of the standard Range syntax (i.e., (x..y).each)?
  2. Either way, what would be the most idiomatic "Ruby way" of accomplishing this (using a Range or otherwise)? Like I said, I'm new to the language; so any guidance you can offer on how to do things in a more typical Ruby style would be much appreciated.
+3  A: 

This question answers yours: http://stackoverflow.com/questions/2583665/about-ruby-range

(2..100).step(2) do |x|
    # your code
end
zildjohn01
That simple, eh? Thanks!
Dan Tao
So, how would I do it backwards?
Dan Tao
+5  A: 

You can't declare a Range with a "step". Ranges don't have steps, they simply have a beginning and an end.

You can certainly iterate over a Range in steps, for example like this:

(2..100).step(2).reverse_each(&method(:p))

But if all you want is to iterate, then what do you need the Range for in the first place? Why not just iterate?

100.step(2, -2, &method(:p))

This has the added benefit that unlike reverse_each it does not need to generate an intermediate array.

Jörg W Mittag
Nice. Exactly what I needed -- and thanks also for clarifying my terminology. Cleared up a lot!
Dan Tao