6

Simple question, is it possible to do a for loop on a range of negative values? Specifically starting at -1 and iterating down to some negative value. for i in -1..x apparently isn't kosher.

Other than the ugly solution of iterating on the absolute values and then applying the sign within the loop.

1

2 Answers 2

4

The problem isn't in the negative numbers, the problem is in the reverse range. If we assume that x < -1 then you have a range (a,b) with a > b.

The default step of a rust range in a for loop is +1, so the loop never executes. If you write it out, C++ style, you'd be saying

for (i=-1; i < x; i++) { ... }

So what you want to do is reverse the range:

for i in (x..=-1).rev()

EDIT: Because (x..-1) does not include -1, we need to change it to (x..=-1). In that case the range will include both x and 1. If we don't want that, we have to fiddle with the x bound as well, e.g. ((x+1)..=-1).rev

Sign up to request clarification or add additional context in comments.

4 Comments

Isn't the step_by parameter supposed to be unsigned?
Whoops. Yes. See my edit. I swear it used to work in the past. That was in the pre-stable days, apparently: internals.rust-lang.org/t/step-by-on-negative-numbers/2231
Note that for i in (x..-1).rev() iterates from -2 down to x, since the range x..-1 does not include the endpoint.
As Sven Marnach points out, (x..-1).rev() starts at -2. It should be (x..=-1).rev().
2

The standard Range type (what you get with a..b) is a half-open increasing range. If you have a range where a >= b, then the range is empty.

If you want to iterate a range in reverse (decreasing) order, then you need to use Iterator::rev to reverse the range, which is enabled by range being a DoubleEndedIterator and providing the reverse iteration next_back.

So in this case, you'd iterate over ((x + 1)..0).rev().

Just as a fun side note, you can also get basically any iterator you want out of iter::successors, by just providing a fn next(&T) -> Option<T>; in this case, |x| x - 1, if that's clearer in a specific use case than reversing an increasing range.

1 Comment

(x..-1).rev() will start at -2. You need to use (x..=-1).rev() instead.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.