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, stride
s 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 map
ping 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
How to Compress of Reduce the Size of an Image Before Uploading to Parse as Pffile? (Swift)
How to Simultaneously Satisfy Constraints, Will Attempt to Recover by Breaking Constraint
How to Disable the Uitableview Selection
Can Afnetworking Return Data Synchronously (Inside a Block)
Table Header Views in Storyboards
Swrevealviewcontroller Without Using Navigationcontroller
Using Custom Fonts in Wkwebview
Why Is Glreadpixels() Failing in This Code in iOS 6.0
Execute Action When Back Bar Button of Uinavigationcontroller Is Pressed
Changing Tint/Background Color of Uitabbar
Always Pass Weak Reference of Self into Block in Arc
How to Change the Device Orientation Programmatically in iOS 6
How Does View Controller Containment Work in iOS 5