With Swift 5, according to your needs, you may choose one of the **four following Playground code examples** in order to solve your problem.
---
# #1. Using `ClosedRange` `reversed()` method
`ClosedRange` has a method called [`reversed()`][1]. `reversed()` method has the following declaration:
func reversed() -> ReversedCollection<ClosedRange<Bound>>
> Returns a view presenting the elements of the collection in reverse order.
*Usage:*
let reversedCollection = (0 ... 5).reversed()
for index in reversedCollection {
print(index)
}
/*
Prints:
5
4
3
2
1
0
*/
As an alternative, you can use `Range` [`reversed()`][2] method:
let reversedCollection = (0 ..< 6).reversed()
for index in reversedCollection {
print(index)
}
/*
Prints:
5
4
3
2
1
0
*/
---
# #2. Using `sequence(first:next:)` function
Swift Standard Library provides a function called [`sequence(first:next:)`][3]. `sequence(first:next:)` has the following declaration:
func sequence<T>(first: T, next: @escaping (T) -> T?) -> UnfoldFirstSequence<T>
> Returns a sequence formed from `first` and repeated lazy applications of `next`.
*Usage:*
let unfoldSequence = sequence(first: 5, next: {
$0 > 0 ? $0 - 1 : nil
})
for index in unfoldSequence {
print(index)
}
/*
Prints:
5
4
3
2
1
0
*/
---
# #3. Using `stride(from:through:by:)` function
Swift Standard Library provides a function called [`stride(from:through:by:)`][4]. `stride(from:through:by:)` has the following declaration:
func stride<T>(from start: T, through end: T, by stride: T.Stride) -> StrideThrough<T> where T : Strideable
> Returns a sequence from a starting value toward, and possibly including, an end value, stepping by the specified amount.
*Usage:*
let sequence = stride(from: 5, through: 0, by: -1)
for index in sequence {
print(index)
}
/*
Prints:
5
4
3
2
1
0
*/
As an alternative, you can use [`stride(from:to:by:)`][5]:
let sequence = stride(from: 5, to: -1, by: -1)
for index in sequence {
print(index)
}
/*
Prints:
5
4
3
2
1
0
*/
---
# #4. Using `AnyIterator` `init(_:)` initializer
`AnyIterator` has an initializer called [`init(_:)`][6]. `init(_:)` has the following declaration:
init(_ body: @escaping () -> AnyIterator<Element>.Element?)
> Creates an iterator that wraps the given closure in its `next()` method.
*Usage:*
var index = 5
guard index >= 0 else { fatalError("index must be positive or equal to zero") }
let iterator = AnyIterator({ () -> Int? in
defer { index = index - 1 }
return index >= 0 ? index : nil
})
for index in iterator {
print(index)
}
/*
Prints:
5
4
3
2
1
0
*/
If needed, you can refactor the previous code by creating an extension method for `Int` and wrapping your iterator in it:
extension Int {
func iterateDownTo(_ endIndex: Int) -> AnyIterator<Int> {
var index = self
guard index >= endIndex else { fatalError("self must be greater than or equal to endIndex") }
let iterator = AnyIterator { () -> Int? in
defer { index = index - 1 }
return index >= endIndex ? index : nil
}
return iterator
}
}
let iterator = 5.iterateDownTo(0)
for index in iterator {
print(index)
}
/*
Prints:
5
4
3
2
1
0
*/
[1]:
[To see links please register here]
[2]:
[To see links please register here]
[3]:
[To see links please register here]
[4]:
[To see links please register here]
[5]:
[To see links please register here]
[6]:
[To see links please register here]