Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a reason that we cannot iterate on "reverse Range" in ruby?

People also ask

How do you iterate backwards in Ruby?

You can use "unshift" method to iterate and add items to new "reversed" array.

What is reverse iteration?

A reverse iterator is made from a bidirectional, or random access iterator which it keeps as a member which can be accessed through base() . To iterate backwards use rbegin() and rend() as the iterators for the end of the collection, and the start of the collection respectively.

What is the simplest way to iterate through the items of an array Ruby?

The Ruby Enumerable#each method is the most simplistic and popular way to iterate individual items in an array. It accepts two arguments: the first being an enumerable list, and the second being a block. It takes each element in the provided list and executes the block, taking the current item as a parameter.

What does .each mean in Ruby?

each is just another method on an object. That means that if you want to iterate over an array with each , you're calling the each method on that array object. It takes a list as it's first argument and a block as the second argument.


A range is just that: something defined by its start and end, not by its contents. "Iterating" over a range doesn't really make sense in a general case. Consider, for example, how you would "iterate" over the range produced by two dates. Would you iterate by day? by month? by year? by week? It's not well-defined. IMO, the fact that it's allowed for forward ranges should be viewed as a convenience method only.

If you want to iterate backwards over a range like that, you can always use downto:

$ r = 10..6
=> 10..6

$ (r.first).downto(r.last).each { |i| puts i }
10
9
8
7
6

Here are some more thoughts from others on why it's tough to both allow iteration and consistently deal with reverse-ranges.


How about (0..1).reverse_each which iterates the range backwards?


Iterating over a range in Ruby with each calls the succ method on the first object in the range.

$ 4.succ
=> 5

And 5 is outside the range.

You can simulate reverse iteration with this hack:

(-4..0).each { |n| puts n.abs }

John pointed out that this will not work if it spans 0. This would:

>> (-2..2).each { |n| puts -n }
2
1
0
-1
-2
=> -2..2

Can't say I really like any of them because they kind of obscure the intent.


Another way is (1..10).to_a.reverse