views:

196

answers:

3
+3  Q: 

about ruby range?

like this

range = (0..10)

how can I get number like this:

0 5 10 

plus five every time but less than 10

if range = (0..20) then i should get this:

0 5 10 15 20
A: 

The step method described in http://ruby-doc.org/core/classes/Range.html should do the job but seriously harms may harm the readability.

Just consider:

(0..20).step(5){|n| print ' first ', n }.each{|n| print ' second ',n }

You may think that step(5) kind of produces a new Range, like why_'s question initially intended. But the each is called on the (0..20) and has to be replaced by another step(5) if you want to "reuse" the 0-5-10-15-20 range.

Maybe you will be fine with something like (0..3).map{|i| i*5}?

But "persisting" the step method's results with .to_a should also work fine.

efi
“seriously harms the readability” – *what*?! Why? How?
Konrad Rudolph
I'd argue that step is more readable than a map of that nature, at least in this case.
Amber
`(0..20).step(5).each{...}.each{...}` will do what you want it to do.
Marc-André Lafortune
@Marc-Andre Lafortune: `(0..20).step(5).each{print '.'}.each{print '!'}`will print`.....!!!!!!!!!!!!!!!!!!!!!`and that's hard to figure out at first glance - at least for me.
efi
@efi: no, it will print .....!!!!! Did you actually try it? The reason is that `step(5)` (with no block) returns an Enumerator that will yield 5 times. This Enumerator is returned by both `each`. What's confusing you is that `step(5){a block}` returns the original enumerable, so further `each` will operate on the full range.
Marc-André Lafortune
@Marc-Andre Lafortune: I actually tried `(0..20).step(5).each{print '.'}.each{print '!'}` in Ruby 1.8.7 and JRuby 1.4.0. In both cases I got 5 times '.' but 20 times '!'. I tried it in IRB (and JIRB) as well as via the normal ruby interpreter. Under Linux and Windows. Strange considering your explanation...
efi
@efi: I must have been day-dreaming. I'm very surprised. The fact that enumerator.each{} returns the base object is unintuitive for me. It's not even spec'ed in rubyspec. I'll check to see if it's only me!
Marc-André Lafortune
+6  A: 

Try using .step() to go through at a given step.

(0..20).step(5) do |n|
    print n,' '
end

gives...

0 5 10 15 20

As mentioned by dominikh, you can add .to_a on the end to get a storable form of the list of numbers: (0..20).step(5).to_a

Amber
and if you want to store the numbers you can use (0..10).step(5).to_a -- this requires ruby >= 1.8.7 though. An alternative is 0.step(10, 5).to_a, which also required ruby >= 1.8.7
dominikh
+2  A: 

Like Dav said, but add to_a:

(0..20).step(5).to_a # [0, 5, 10, 15, 20]
name
You generally don’t need to add `to_a` unless you really *do* need an array.
Konrad Rudolph