How to iterate for loop in reverse order in swift?
Xcode 6 beta 4 added two functions to iterate on ranges with a step other than one:
stride(from: to: by:)
, which is used with exclusive ranges and stride(from: through: by:)
, which is used with inclusive ranges.
To iterate on a range in reverse order, they can be used as below:
for index in stride(from: 5, to: 1, by: -1) {
print(index)
}
//prints 5, 4, 3, 2
for index in stride(from: 5, through: 1, by: -1) {
print(index)
}
//prints 5, 4, 3, 2, 1
Note that neither of those is a Range
member function. They are global functions that return either a StrideTo
or a StrideThrough
struct, which are defined differently from the Range
struct.
A previous version of this answer used the by()
member function of the Range
struct, which was removed in beta 4. If you want to see how that worked, check the edit history.
Apply the reverse function to the range to iterate backwards:
For Swift 1.2 and earlier:
// Print 10 through 1
for i in reverse(1...10) {
println(i)
}
It also works with half-open ranges:
// Print 9 through 1
for i in reverse(1..<10) {
println(i)
}
Note: reverse(1...10)
creates an array of type [Int]
, so while this might be fine for small ranges, it would be wise to use lazy
as shown below or consider the accepted stride
answer if your range is large.
To avoid creating a large array, use lazy
along with reverse()
. The following test runs efficiently in a Playground showing it is not creating an array with one trillion Int
s!
Test:
var count = 0
for i in lazy(1...1_000_000_000_000).reverse() {
if ++count > 5 {
break
}
println(i)
}
For Swift 2.0 in Xcode 7:
for i in (1...10).reverse() {
print(i)
}
Note that in Swift 2.0, (1...1_000_000_000_000).reverse()
is of type ReverseRandomAccessCollection<(Range<Int>)>
, so this works fine:
var count = 0
for i in (1...1_000_000_000_000).reverse() {
count += 1
if count > 5 {
break
}
print(i)
}
For Swift 3.0 reverse()
has been renamed to reversed()
:
for i in (1...10).reversed() {
print(i) // prints 10 through 1
}