模仿“C式循环”
这并不完美,但您可以使用max(0, ...)
将范围的上限包装起来,以确保它永远不会取负值。
let foo : [Int] = []
for i in 0..<max(0,foo.count-1) {
print(i)
}
然而,我更喜欢已经在其他答案中提到的from.stride(to:by)
解决方案。
然而,我认为有价值的是明确指出,from.stride(to:by)
如果尝试通过正步幅向小于from的数字进行跨越,则会整洁地返回一个空的StrideTo
(或者,如果转换为数组:一个空数组)。例如,从0
到-42
以1
的步幅跨越不会尝试穿过"∞ -> -∞ -> -42"
(即错误情况),而只是返回一个空的StrideTo
(应该如此):
Array(0.stride(to: -42, by: 1))
for i in 0.stride(to: foo.count-1, by: 1) {
print(i)
}
应用场景1:列举一个数组中除最后一个元素外的所有元素
对于这个特定的用例,简单的解决方案是使用dropLast()
(如Sulthan在您的问题的评论中所述),然后使用forEach
。
let foo = Array(1...5)
foo.dropLast().forEach { print($0) } // 1 2 3 4
或者,如果您需要更多关于要删除哪些内容的控制,请向数组应用过滤器。
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)
foo(0.5...0.9)
或者,如果您想特别枚举该区间内包含的(可能的)整数,请使用适合您目的的扩展:
protocol MyDoubleBounds {
func ceilToInt() -> Int
}
extension Double: MyDoubleBounds {
func ceilToInt() -> Int {
return Int(ceil(self))
}
}
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)
}
for (i, intVal) in (0.6...0.9).enumerateIntegers() {
print(i, intVal)
}
for
循环来迭代或清理输入,例如for i in 0 ..< max(0, -1)
。或者使用while
循环。 - Sulthanmax
实际上是一个相当不错的想法!谢谢。但仍然不如 C 风格的简洁 :( - Khanh Nguyen