Working with Reverse Ranges in Swift

Update: Xcode 6 beta 4 brought changes pertaining iterating through ranges. The content below is thus outdate. See this post.

Reverse ranges have a weird behaviour in Swift. For example:

for index in 5..<1 {
    println(index)
}

The code above results in an infinite loop. That's because the loop starts from 5 and increments at each iteration, never actually reaching 1.

In order to get the expected result of printing the numbers from 5 to 2, one should use the by() member function of the range structure, passing in -1 as the value for the step:

for index in (5..<1).by(-1) {
    println(index)
}

Note it’s necessary to enclose the range inside parentheses.

However, there’s a catch. Iterating in reverse through the open interval, built with ..<, will yield the expected behaviour, which in the example above is to print the values 5, 4, 3 and 2. However, if the closed range operator - ... - is used, instead of going until 1, the loop will stop at 3. Weird, but that’s because a...b is defined as a..<advance(b,1).

Another option to iterate through a reverse range is to use the ReverseRange() function, which will work as expected for closed ranges:

for index in ReverseRange(range:1...5) {
    println(index)
}

The code above prints 5, 4, 3, 2 and 1 as expected. However, the same code with an open range operator will print starting from 4, since the reverse of 1..<5 is actually 4...1.

Adapted from my answer on Stack Overflow