当我在 Playground 中使用 for 循环时,一切正常,直到我将 for 循环的第一个参数更改为最大值。(按降序迭代)
这是一个错误吗?其他人有吗?
for index in 510..509
{
var a = 10
}
显示将要执行的迭代次数的计数器一直在滴答作响……

当我在 Playground 中使用 for 循环时,一切正常,直到我将 for 循环的第一个参数更改为最大值。(按降序迭代)
这是一个错误吗?其他人有吗?
for index in 510..509
{
var a = 10
}
显示将要执行的迭代次数的计数器一直在滴答作响……

Xcode 6 beta 4 添加了两个函数来迭代范围,而不是一个步骤:
stride(from: to: by:),用于独占范围和stride(from: through: by:),用于包含范围。
要以相反的顺序迭代一个范围,它们可以如下使用:
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
请注意,这些都不是Range成员函数。它们是返回 aStrideTo或StrideThroughstruct 的全局函数,它们的定义与Rangestruct 不同。
此答案的先前版本使用by()了 struct 的成员函数,该Range函数已在 beta 4 中删除。如果您想了解它是如何工作的,请查看编辑历史记录。
将 reverse 函数应用于范围以向后迭代:
对于Swift 1.2及更早版本:
// Print 10 through 1
for i in reverse(1...10) {
println(i)
}
它也适用于半开范围:
// Print 9 through 1
for i in reverse(1..<10) {
println(i)
}
注意: reverse(1...10)创建一个 type 的数组[Int],因此虽然这对于小范围可能很好,但如果您的范围很大,则使用lazy如下所示或考虑接受的答案是明智的。stride
为避免创建大型数组,lazy请与reverse(). 以下测试在 Playground 中有效运行,表明它没有创建一个具有 1 万亿Ints 的数组!
测试:
var count = 0
for i in lazy(1...1_000_000_000_000).reverse() {
if ++count > 5 {
break
}
println(i)
}
对于Xcode 7 中的Swift 2.0 :
for i in (1...10).reverse() {
print(i)
}
请注意,在 Swift 2.0 中,(1...1_000_000_000_000).reverse()是 type ReverseRandomAccessCollection<(Range<Int>)>,所以这很好用:
var count = 0
for i in (1...1_000_000_000_000).reverse() {
count += 1
if count > 5 {
break
}
print(i)
}
对于Swift 3.0 reverse()已重命名为reversed():
for i in (1...10).reversed() {
print(i) // prints 10 through 1
}
为 Swift 3 更新
下面的答案是可用选项的摘要。选择最适合您需求的一种。
reversed: 范围内的数字向前
for index in 0..<5 {
print(index)
}
// 0
// 1
// 2
// 3
// 4
落后
for index in (0..<5).reversed() {
print(index)
}
// 4
// 3
// 2
// 1
// 0
reversed: 中的元素SequenceTypelet animals = ["horse", "cow", "camel", "sheep", "goat"]
向前
for animal in animals {
print(animal)
}
// horse
// cow
// camel
// sheep
// goat
落后
for animal in animals.reversed() {
print(animal)
}
// goat
// sheep
// camel
// cow
// horse
reversed: 有索引的元素有时在遍历集合时需要索引。为此,您可以使用enumerate(),它返回一个元组。元组的第一个元素是索引,第二个元素是对象。
let animals = ["horse", "cow", "camel", "sheep", "goat"]
向前
for (index, animal) in animals.enumerated() {
print("\(index), \(animal)")
}
// 0, horse
// 1, cow
// 2, camel
// 3, sheep
// 4, goat
落后
for (index, animal) in animals.enumerated().reversed() {
print("\(index), \(animal)")
}
// 4, goat
// 3, sheep
// 2, camel
// 1, cow
// 0, horse
请注意,正如 Ben Lachman 在他的回答中指出的那样,您可能想要做.enumerated().reversed()而不是.reversed().enumerated()(这会使索引号增加)。
步幅是不使用范围进行迭代的方式。有两种形式。代码末尾的注释显示了范围版本将是什么(假设增量大小为 1)。
startIndex.stride(to: endIndex, by: incrementSize) // startIndex..<endIndex
startIndex.stride(through: endIndex, by: incrementSize) // startIndex...endIndex
向前
for index in stride(from: 0, to: 5, by: 1) {
print(index)
}
// 0
// 1
// 2
// 3
// 4
落后
将增量大小更改为-1允许您向后退。
for index in stride(from: 4, through: 0, by: -1) {
print(index)
}
// 4
// 3
// 2
// 1
// 0
注意to和through区别。
以 2 为增量前进
let animals = ["horse", "cow", "camel", "sheep", "goat"]
我2在这个例子中使用只是为了展示另一种可能性。
for index in stride(from: 0, to: 5, by: 2) {
print("\(index), \(animals[index])")
}
// 0, horse
// 2, camel
// 4, goat
落后
for index in stride(from: 4, through: 0, by: -1) {
print("\(index), \(animals[index])")
}
// 4, goat
// 3, sheep
// 2, camel
// 1, cow
// 0, horse
@matt 有一个有趣的解决方案,他定义了自己的反向运算符并调用它>>>。它不需要太多的代码来定义,它的使用方式如下:
for index in 5>>>0 {
print(index)
}
// 4
// 3
// 2
// 1
// 0
斯威夫特 4起
for i in stride(from: 5, to: 0, by: -1) {
print(i)
}
//prints 5, 4, 3, 2, 1
for i in stride(from: 5, through: 0, by: -1) {
print(i)
}
//prints 5, 4, 3, 2, 1, 0
使用 Swift 5,根据您的需要,您可以选择以下四个 Playground 代码示例之一来解决您的问题。
ClosedRange reversed()方法ClosedRange有一个方法叫做reversed(). reversed()方法具有以下声明:
func reversed() -> ReversedCollection<ClosedRange<Bound>>
返回以相反顺序呈现集合元素的视图。
用法:
let reversedCollection = (0 ... 5).reversed()
for index in reversedCollection {
print(index)
}
/*
Prints:
5
4
3
2
1
0
*/
作为替代方案,您可以使用Range reversed()以下方法:
let reversedCollection = (0 ..< 6).reversed()
for index in reversedCollection {
print(index)
}
/*
Prints:
5
4
3
2
1
0
*/
sequence(first:next:)功能Swift 标准库提供了一个名为sequence(first:next:). sequence(first:next:)有以下声明:
func sequence<T>(first: T, next: @escaping (T) -> T?) -> UnfoldFirstSequence<T>
返回
first由next.
用法:
let unfoldSequence = sequence(first: 5, next: {
$0 > 0 ? $0 - 1 : nil
})
for index in unfoldSequence {
print(index)
}
/*
Prints:
5
4
3
2
1
0
*/
stride(from:through:by:)功能Swift 标准库提供了一个名为stride(from:through:by:). stride(from:through:by:)有以下声明:
func stride<T>(from start: T, through end: T, by stride: T.Stride) -> StrideThrough<T> where T : Strideable
返回从起始值到(可能包括)结束值的序列,步进指定的量。
用法:
let sequence = stride(from: 5, through: 0, by: -1)
for index in sequence {
print(index)
}
/*
Prints:
5
4
3
2
1
0
*/
作为替代方案,您可以使用stride(from:to:by:):
let sequence = stride(from: 5, to: -1, by: -1)
for index in sequence {
print(index)
}
/*
Prints:
5
4
3
2
1
0
*/
AnyIterator init(_:)初始化器AnyIterator有一个名为init(_:). init(_:)有以下声明:
init(_ body: @escaping () -> AnyIterator<Element>.Element?)
创建一个将给定闭包包装在其
next()方法中的迭代器。
用法:
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
*/
如果需要,您可以通过创建扩展方法Int并将迭代器包装在其中来重构以前的代码:
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
*/
对于 Swift 2.0 及更高版本,您应该在范围集合上应用 reverse
for i in (0 ..< 10).reverse() {
// process
}
它已在 Swift 3.0 中重命名为 .reversed()
在 Swift 4 及更高版本中
let count = 50//For example
for i in (1...count).reversed() {
print(i)
}
斯威夫特 4.0
for i in stride(from: 5, to: 0, by: -1) {
print(i) // 5,4,3,2,1
}
如果要包含该to值:
for i in stride(from: 5, through: 0, by: -1) {
print(i) // 5,4,3,2,1,0
}
至于 Swift 2.2 , Xcode 7.3 (10,June,2016) :
for (index,number) in (0...10).enumerate() {
print("index \(index) , number \(number)")
}
for (index,number) in (0...10).reverse().enumerate() {
print("index \(index) , number \(number)")
}
输出 :
index 0 , number 0
index 1 , number 1
index 2 , number 2
index 3 , number 3
index 4 , number 4
index 5 , number 5
index 6 , number 6
index 7 , number 7
index 8 , number 8
index 9 , number 9
index 10 , number 10
index 0 , number 10
index 1 , number 9
index 2 , number 8
index 3 , number 7
index 4 , number 6
index 5 , number 5
index 6 , number 4
index 7 , number 3
index 8 , number 2
index 9 , number 1
index 10 , number 0
如果一个人想要反向遍历一个数组(Array或更一般地说是任何一个SequenceType)。你有几个额外的选择。
首先,您可以reverse()像往常一样遍历数组并循环它。但是我更喜欢使用enumerate()大部分时间,因为它输出一个包含对象及其索引的元组。
这里要注意的一件事是,以正确的顺序调用它们很重要:
for (index, element) in array.enumerate().reverse()
按降序生成索引(这是我通常所期望的)。然而:
for (index, element) in array.reverse().enumerate()(与 NSArray 更接近reverseEnumerator)
向后遍历数组,但输出升序索引。
您可以使用 reversed() 方法轻松反转值。
var i:Int
for i in 1..10.reversed() {
print(i)
}
reversed() 方法反转值。
您可以考虑改用 C-Stylewhile循环。这在 Swift 3 中运行良好:
var i = 5
while i > 0 {
print(i)
i -= 1
}
var sum1 = 0
for i in 0...100{
sum1 += i
}
print (sum1)
for i in (10...100).reverse(){
sum1 /= i
}
print(sum1)
只需一步.reverse()即可反转数组
var arrOfnum = [1,2,3,4,5,6]
arrOfnum.reverse()
对我来说,这是最好的方式。
var arrayOfNums = [1,4,5,68,9,10]
for i in 0..<arrayOfNums.count {
print(arrayOfNums[arrayOfNums.count - i - 1])
}