replaceSwift 2.2中的C风格的循环

Swift 2.2弃用了C风格的循环。 但是,在某些情况下,新的范围运算符只是工作不一样。

for var i = 0; i < -1; ++i { ... } 

 for i in 0..<-1 { ... } 

后者在运行时会失败。 我可以用if包裹循环,但是有点混乱。 有时这种循环是有用的。

有什么想法吗?

用例

  1. 您需要枚举数组中的所有元素,除了最后一个。
  2. 你需要枚举所有整数在十进制范围内,但范围可以像[0.5,0.9],所以没有整数(在一些math后),这将导致一个空循环。

虽然不是“漂亮”,但可以使用stride

 for var i in 0.stride(to: -1, by: -1) { print(i) } 

模仿“C式循环”

不完全漂亮,但你可以用范围上限max(0, ..)来确定它从不取负值。

 let foo : [Int] = [] for i in 0..<max(0,foo.count-1) { print(i) } 

但是,我更喜欢from.stride(to:by)解决scheme(在其他答案中已经提到过,例如参见Michael的答案)。

然而,我认为明确地指出from.stride(to:by)整齐地返回一个空的StrideTo (或者,如果转换为数组:一个空数组),如果试图跨越一个小于而是通过积极的步伐。 例如,从0-42 ,不会试图通过"∞ -> -∞ -> -42" (即错误情况) StrideTo ,而是简单地返回一个空的StrideTo (它应该):

 Array(0.stride(to: -42, by: 1)) // [] // -> equivalent to your C loop: for i in 0.stride(to: foo.count-1, by: 1) { print(i) } 

使用案例1:枚举除数组的最后一个元素外的所有元素

对于这个特定的用例,一个简单的解决scheme是使用dropLast() (在Sulthan中对你的问题的评论中描述),然后是forEach

 let foo = Array(1...5) foo.dropLast().forEach { print($0) } // 1 2 3 4 

或者,如果您需要更多控制要删除的内容,请将filter应用于您的arrays

 let foo = Array(1...5) foo.filter { $0 < foo.count }.forEach { print($0) } // 1 2 3 4 

用例2:枚举小数范围内的所有整数,允许此枚举为空

对于你的十进制/双闭区间示例( [0.6, 0.9] ;一个区间而不是Swift语法中的区间),可以将闭区间转换为一个整数范围(使用ceil函数),并将forEach后者

 let foo : (ClosedInterval<Double>) -> () = { (Int(ceil($0.start))..<Int(ceil($0.end))) .forEach { print($0) } } foo(0.5...1.9) // 1 foo(0.5...0.9) // nothing 

或者,如果您特意要枚举此区间中包含的(可能的)整数, 用作符合您的目的的扩展名:

 protocol MyDoubleBounds { func ceilToInt() -> Int } extension Double: MyDoubleBounds { func ceilToInt() -> Int { return Int(ceil(self)) // no integer bounds check in this simple example } } extension ClosedInterval where Bound: MyDoubleBounds { func enumerateIntegers() -> EnumerateSequence<(Range<Int>)> { return (self.start.ceilToInt() ..< self.end.ceilToInt()) .enumerate() } } 

用法示例:

 for (i, intVal) in (1.3...3.2).enumerateIntegers() { print(i, intVal) } /* 0 2 1 3 */ for (i, intVal) in (0.6...0.9).enumerateIntegers() { print(i, intVal) } /* nothing */ 

作为参考:在swift 3.0中,现在定义了全局,这使得循环看起来更自然:

 for i in stride(from: 10, to: 0, by: -1){ print(i) } /* 10 9 8 7 6 5 4 3 2 1 */ 

对于Swift 3,需要更改“索引”

 for var index in stride(from: 0, to: 10, by: 1){}