Swift 2.2弃用了C风格的循环.但是在某些情况下,新的范围运算符不起作用.
for var i = 0; i < -1; ++i { ... }
Run Code Online (Sandbox Code Playgroud)
和
for i in 0..<-1 { ... }
Run Code Online (Sandbox Code Playgroud)
后者将在运行时失败.我可以用一个包裹循环if,但它有点混乱.有时候这种循环很有用.
有什么想法吗?
用例
Mic*_*ael 20
虽然它不是"漂亮",但您可以使用stride:
for var i in 0.stride(to: -1, by: -1) {
print(i)
}
Run Code Online (Sandbox Code Playgroud)
不完全漂亮,但你可以包装范围:s上限用a max(0, ..)来确定它永远不会取负值.
let foo : [Int] = []
for i in 0..<max(0,foo.count-1) {
print(i)
}
Run Code Online (Sandbox Code Playgroud)
然而,我更喜欢from.stride(to:by)解决方案(其他答案中已经提到过,例如迈克尔:答案).
我认为这是有价值明确指出,但是,from.stride(to:by)整齐地返回一个空StrideTo(或者,如果转换为一个数组:空数组)如果试图趟过到一个数字,小于从而是通过积极的步伐.例如,从跨越0到-42由1不会试图通过阔步一路"? -> -? -> -42"(即,一个错误的情况下),而只是返回一个空的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)
}
Run Code Online (Sandbox Code Playgroud)
对于这个特定的用例,一个简单的解决方案是使用dropLast()(如Sulthan在您的问题的评论中所描述的),然后是forEach.
let foo = Array(1...5)
foo.dropLast().forEach { print($0) } // 1 2 3 4
Run Code Online (Sandbox Code Playgroud)
或者,如果您需要更多地控制要删除的内容,请将过滤器应用于阵列
let foo = Array(1...5)
foo.filter { $0 < foo.count }.forEach { print($0) } // 1 2 3 4
Run Code Online (Sandbox Code Playgroud)
对于您的十进制/双闭区间示例([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
Run Code Online (Sandbox Code Playgroud)
或者,如果您特别想要枚举此区间中包含的(可能的)整数; 用作适合您目的的扩展名:
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()
}
}
Run Code Online (Sandbox Code Playgroud)
用法示例:
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 */
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4419 次 |
| 最近记录: |