How to Iterate For Loop in Reverse Order in Swift

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.

Swift for loop backwards

You can use stride(through:by:) or stride(to:by:) on anything that conforms to the Strideable protocol. The first one includes the listed value, the second stops one before it.

example:

for i in 99.stride(through: 1, by: -1) { // creates a range of 99...1
print("\(i) bottles of beer on the wall, \(i) bottles of beer.")
print("Take one down and pass it around, \(i-1) bottles of beer on the wall.")
}

You can also use reversed():

for i in (1...99).reversed() {
print("\(i) bottles of beer on the wall, \(i) bottles of beer.")
print("Take one down and pass it around, \(i-1) bottles of beer on the wall.")
}

How to iterate backwards in a for loop with a range

You cannot do that with a for ... in ... statement. When using a for ... in ... statement, both the index variable and the range are immutable and you have no control over how the range is iterated through.

However, there are several alternatives you can use, such as while loops, strides and recursion.

Example for how to iterate over a range in descending order using a stride:

stride(from: upperIndex, through: lowerIndex, by: -1).forEach({ index in
let rotationValue = newArray.remove(at: index)
newArray.insert(rotationValue, at: 0)
})

Reverse a for loop of an array

As the name implies you can reverse an array just with reversed().

Your code is rather objective-c-ish. A better way to enumerate the array is fast enumeration because you actually don't need the index.

for coord in arrayLocations { ...

and

for coord in arrayLocations.reversed() { ...

However there is a still swiftier way mapping the arrays

func createCoordinatePoly() {
arrayLocationOffset.append(contentsOf: arrayLocations.map{coord270(coord: $0)})
arrayLocationOffset.append(contentsOf: arrayLocations.reversed().map{coord90(coord: $0)})
debugPrint("aggiunto array poly \(arrayLocationOffset.count)")
}

What's a good way to iterate backwards through the Characters of a String?

The reversed function reverses a C: CollectionType and returns a ReversedCollection:

for char in "string".characters.reversed() {
// ...
}

If you find that reversed pre-reverses the string, try:

for char in "string".characters.lazy.reversed() {
// ...
}

lazy returns a lazily evaluated sequence (LazyBidirectionalCollection) then reversed() returns another LazyBidirectionalCollection that is visited in reverse.

Reverse Range in Swift

Update For latest Swift 3 (still works in Swift 4)

You can use the reversed() method on a range

for i in (1...5).reversed() { print(i) } // 5 4 3 2 1

Or stride(from:through:by:) method

for i in stride(from:5,through:1,by:-1) { print(i) } // 5 4 3 2 1

stide(from:to:by:) is similar but excludes the last value

for i in stride(from:5,to:0,by:-1) { print(i) } // 5 4 3 2 1

Update For latest Swift 2

First of all, protocol extensions change how reverse is used:

for i in (1...5).reverse() { print(i) } // 5 4 3 2 1

Stride has been reworked in Xcode 7 Beta 6. The new usage is:

for i in 0.stride(to: -8, by: -2) { print(i) } // 0 -2 -4 -6
for i in 0.stride(through: -8, by: -2) { print(i) } // 0 -2 -4 -6 -8

It also works for Doubles:

for i in 0.5.stride(to:-0.1, by: -0.1) { print(i) }

Be wary of floating point compares here for the bounds.

Earlier edit for Swift 1.2: As of Xcode 6 Beta 4, by and ReverseRange don't exist anymore :[

If you are just looking to reverse a range, the reverse function is all you need:

for i in reverse(1...5) { println(i) } // prints 5,4,3,2,1

As posted by 0x7fffffff there is a new stride construct which can be used to iterate and increment by arbitrary integers. Apple also stated that floating point support is coming.

Sourced from his answer:

for x in stride(from: 0, through: -8, by: -2) {
println(x) // 0, -2, -4, -6, -8
}

for x in stride(from: 6, to: -2, by: -4) {
println(x) // 6, 2
}

Swift range operator for i = mymax; i >= 0 i--

It's easy to reverse the loop. User reversed function.

Swift 3

let myMax = 20
for i in (1.. print(i)
}

You can also use stride as @ZaidPathan said :

This question have all answers with all versions : How to iterate for loop in reverse order in swift?



Related Topics



Leave a reply



Submit