如何在swift中以相反的顺序迭代循环?
当我在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成员函数。 它们是返回StrideTo或StrideThrough结构的全局函数, StrideThrough结构的定义与Range结构不同。 
 此答案的以前版本使用了Range结构的by()成员函数,该函数在beta 4中已被删除。如果要查看其工作原理,请检查编辑历史logging。 
将反转函数应用于范围以反向迭代:
对于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)会创build一个[Int]types的数组,所以对于小范围这可能是正确的,如下所示使用lazy会比较明智,或者如果范围很大。 
 为避免创build大数组,请使用lazy和reverse() 。 以下testing在Playground中高效运行,表明它不会创build一个具有一万亿个Int的数组! 
testing:
 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()的types是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
下面的答案是可用选项的摘要。 select一个最适合您的需求。
  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 : SequenceType元素 
 let 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() (这会使索引号增加)。 
迈步:数字
步幅是迭代的方式,而不使用范围。 有两种forms。 代码末尾的注释显示范围版本将会是什么(假定增量大小为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 
注意通和差别。
步幅:SequenceType的元素
前进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])") } // 0, horse // 1, cow // 2, camel // 3, sheep // 4, goat 
笔记
- 
@matt有一个有趣的解决scheme ,他定义了自己的逆运算符并将其称为 >>>。 它不需要太多的代码来定义和使用像这样:for index in 5>>>0 { print(index) } // 4 // 3 // 2 // 1 // 0
- 
查看C风格从Swift中删除的循环3 
斯威夫特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 2.0及以上版本,您应该在范围集合上应用反转
 for i in (0 ..< 10).reverse() { // process } 
它已被重命名为.reversed()在Swift 3.0
使用Swift 3,根据您的需要,您可以select以下八种Playground代码实现中的一种来解决您的问题。
  #1。 使用CountableClosedRange reversed()方法 
  CountableClosedRange有一个名为reversed()的方法。  reversed()方法具有以下声明: 
 func reversed() -> ReversedRandomAccessCollection<CountableClosedRange<Bound>> 
返回以相反顺序呈现集合元素的视图。
用法:
 let reversedRandomAccessCollection = (0 ... 5).reversed() for index in reversedRandomAccessCollection { print(index) } /* Prints: 5 4 3 2 1 0 */ 
  #2。 使用CountableRange reversed()方法 
  CountableRange有一个名为reversed()的方法。  reversed()方法具有以下声明: 
 func reversed() -> ReversedRandomAccessCollection<CountableRange<Bound>> 
返回以相反顺序呈现集合元素的视图。
用法:
 let reversedRandomAccessCollection = (0 ..< 6).reversed() for index in reversedRandomAccessCollection { print(index) } /* Prints: 5 4 3 2 1 0 */ 
  #3。 使用sequence(first:next:)function 
  Swift标准库提供了一个称为sequence(first:next:)的函数。  sequence(first:next:)具有以下声明: 
 func sequence<T>(first: T, next: @escaping (T) -> T?) -> UnfoldSequence<T, (T?, Bool)> 
返回
next重复延迟应用程序形成的序列。
用法:
 let unfoldSequence = sequence(first: 5, next: { $0 - 1 >= 0 ? $0 - 1 : nil }) for index in unfoldSequence { print(index) } /* Prints: 5 4 3 2 1 0 */ 
  #4。 使用stride(from:through:by:)函数 
  Swift标准库提供了一个名为stride(from:through:by:)的函数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 
返回值序列
(self, self + stride, self + 2 * stride, … last),其中last是最后一个小于等于end。
用法:
 let sequence = stride(from: 5, through: 0, by: -1) for index in sequence { print(index) } /* Prints: 5 4 3 2 1 0 */ 
  #5。 使用stride(from:to:by:)函数 
  Swift标准库提供了一个名为stride(from:to:by:)的函数stride(from:to:by:) 。  stride(from:to:by:)具有以下声明: 
 func stride<T>(from start: T, to end: T, by stride: T.Stride) -> StrideTo<T> where T : Strideable 
返回值序列
(self, self + stride, self + 2 * stride, … last),其中last是最后一个小于end。
用法:
 let sequence = stride(from: 5, to: -1, by: -1) for index in sequence { print(index) } /* Prints: 5 4 3 2 1 0 */ 
  #6。 使用AnyIterator init(_:)初始值设定项 
  AnyIterator有一个名为init(_:)的初始化器。  init(_:)具有以下声明: 
 init<I>(_ base: I) where I : IteratorProtocol, I.Element == Element 
创build一个包装基础迭代器的迭代器,但其types仅取决于基础迭代器的元素types。
用法:
 var index = 5 guard index >= 0 else { fatalError("index must be positive or equal to zero") } let iterator = AnyIterator<Int>({ defer { index = index - 1 } return index >= 0 ? index : nil }) for index in iterator { print(index) } /* Prints: 5 4 3 2 1 0 */ 
  #7。 使用AnyIterator init(_:)初始值设定项 
  AnyIterator有一个名为init(_:)的初始化器。  init(_:)具有以下声明: 
 init(_ body: @escaping () -> AnyIterator.Element?) 
创build一个将给定闭包封装在
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 */ 
  #8。 使用自定义Int扩展方法 
 你可以通过为Int创build一个扩展方法并将你的迭代器包装在其中来重构以前的代码: 
 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 */ 
 如果有人想要反过来遍历数组 (或更一般的任何SequenceType )。 你有一些额外的select。 
 首先你可以reverse()数组,并像平常一样循环。 不过,我更喜欢使用enumerate() ,因为它输出一个包含对象的元组,并且它是索引。 
这里要注意的一点是,以正确的顺序调用这些是非常重要的:
 for (index, element) in array.enumerate().reverse() 
以降序产生索引(这是我通常所期望的)。 然而:
  for (index, element) in array.reverse().enumerate() (这更接近于NSArray的reverseEnumerator ) 
向后走数组,但输出升序索引。
至于Swift 2.2,Xcode 7.3(2016年10月10日):
 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 
Swift 4.0
 for i in stride(from: 5, to: 0, by: -1) { print(i) // 5,4,3,2,1 } 
如果你想包含的价值:
 for i in stride(from: 5, through: 0, by: -1) { print(i) // 5,4,3,2,1,0 } 
 var sum1 = 0 for i in 0...100{ sum1 += i } print (sum1) for i in (10...100).reverse(){ sum1 /= i } print(sum1) 
 您可以考虑使用C-Style while循环。 这在Swift 3中运行得很好: 
 var i = 5 while i > 0 { print(i) i -= 1 }