【发布时间】:2016-07-13 01:27:45
【问题描述】:
我想知道关于 Swift 2.2 中非 +1 递增迭代器循环的最佳解决方案,因为旧样式现已弃用:
for (var i = 0; i < planets.count; i += 1) {
let string = planets[i]
if (string == "Venus" || string == "Saturn") {
i += 2
}
}
我的第一个解决方案是使用while,它有效
var i = 0
while i < planets.count {
let string = planets[i]
if (string == "Venus" || string == "Saturn") {
i += 2
}
i += 1
}
但在整个代码中多次使用它并不是很方便。所以我创建了一个似乎也可以工作的 Array 扩展:
extension Array {
func loopIncrement(callback: (inout i: Int) -> ()) {
var index: Int = 0
while index < self.count {
callback(i: &index)
index += 1
}
}
func loopDecrement(callback: (inout i: Int) -> ()) {
var index: Int = self.count - 1
while index >= 0 {
callback(i: &index)
index -= 1
}
}
}
像这样使用它:
planets.loopIncrement { (i) in
let string = planets[i]
if (string == "Venus" || string == "Saturn") {
i += 2
}
}
planets.loopDecrement { (i) in
let string = planets[i]
if (string == "Venus" || string == "Saturn") {
i -= 2
}
}
目前这很好,但我相信有更快捷的方法来解决这个问题。
所以让我们在这里开始讨论。非常感谢任何帮助!
如果你想看看,这里是 Playground 文件:NonPlusOneIncrementLoops.playground
示例:
在以下示例中,您可以看到需要实时更改循环索引的地方。
有一个 printObject 数组,其中包含 PrintObject 类,这些类定义了应将其 printText 打印到调试区域的次数。 printCount 属性是随机生成的,因此在循环之前是未知的。
class PrintObject {
var printCount: Int = 0
var printText: String = "<Missing>"
}
var printObjects = [PrintObject]()
for i in 0...6 {
let randomCount = Int(arc4random_uniform(2)) + 1
let printObject = PrintObject()
printObject.printCount = randomCount
printObject.printText = "This is line \(i)"
printObjects.append(printObject)
}
printObjects.loopIncrement { (i) in
let printObject = printObjects[i]
printObject.printCount -= 1
if printObject.printCount > 0 {
i -= 1
}
print(printObject.printText)
}
这显然是一个微不足道的例子,但它可能会让一些人更清楚在哪些情况下更改循环索引是有意义的。
【问题讨论】:
-
除了根据条件不同地增加循环索引之外,您还想达到什么目的?
-
就是这样。讨论仅基于此。
-
在 for 循环中更改迭代器是 any 语言中的错误代码。您能否添加完整的用例?您如何使用行星(为什么要跳过下一个行星?)?
for-loop没有一个很好的替代品,有很多,而且每一个都用于不同的用例。 -
您能详细说明为什么在循环内更改迭代器是个坏主意吗?
-
关于 printObjects 示例 - 在内部添加另一个嵌套循环 (for...i)。对我来说,这似乎是更清洁的方法。
标签: arrays swift for-loop iterator