Swift:如何执行任务n-1次,其中n是数组的长度?

时间:2015-07-08 11:54:48

标签: swift

我来到这里:

for x in 1...(myArray.count - 1) { task() }

非常难看。还有更好的方法吗?

3 个答案:

答案 0 :(得分:5)

你必须要小心,好像数组是空的,这会崩溃:

let a: [Int] = []
let range = 0..<a.count-1
// fatal error: Can't form Range with end < start

Strides没有这个问题(因为Strideable事情必须是Comparable)所以你可以这样做:

for _ in stride(from: 0, to: a.count - 1, by: 1) {
    // will only execute if a.count > 2
    print("blah")
}

或者,如果你保护它,你可以使用dropFirst

for _ in (a.isEmpty ? [] : dropFirst(a))  {
    print("blah")
}

我强烈建议反对尝试通过创建运行少于计数次数的伪for循环来使这看起来更整洁。 Swift中没有forEachrepeat函数是有原因的。这些循环一开始看起来不错,但是它们会产生很多错误(例如,returncontinue不会按照您的预期方式运行,而且通常认为它不好用使用高阶函数进行外部变异 - 而常规for循环可能会出现突变/副作用。)

最新的扩展类型解决方案可能是扩展Array以做一个安全的drop-first:

extension Array {
    // version of dropFirst that returns empty array for both
    // empty and single-element array
    func safeDropFirst() -> ArraySlice<T> {
        return self.isEmpty ? [] : dropFirst(self)
    }
}

for _ in myArray.safeDropFirst() {
    doThing()
}

答案 1 :(得分:4)

不是更好,但是:

for _ in 1..<myArray.count { task() }

但如果myArray为空,则会崩溃(感谢,Airspeed Velocity)。

如果您因某种原因碰巧需要这么多,您可以提供自己的“循环抽象”并处理该问题:

func repeatArray<T>(arr: [T], @noescape f: () -> Void) {
    if !arr.isEmpty {
        for _ in 1..<arr.count {
            f()
        }
    }
}

repeatArray(myArray) {
    task()
}

答案 2 :(得分:0)

这是Swift 2的一种方式:

for x in myArray where x != myArray.first { task() }
相关问题