用动态范围表示快速循环

时间:2016-10-16 12:22:24

标签: swift for-loop iteration swift3

...或者如何在for循环条件中使用索引

嘿,伙计们 由于我们在swift 3中没有用于循环的c风格,我似乎无法找到一种方法来表达更复杂的循环,所以也许你可以帮助我。

如果我要写这个

for(int i=5; num/i > 0; i*=5)

在swift 3中我该怎么做?

我来的关闭是:

for i in stride(from: 5, through: num, by: 5) where num/i > 0 

但是,如果我是:5,25,125等,这当然会一次迭代5个块。

有什么想法吗?

由于

2 个答案:

答案 0 :(得分:5)

使用辅助函数(最初在Converting a C-style for loop that uses division for the step to Swift 3定义)

public func sequence<T>(first: T, while condition: @escaping (T)-> Bool, next: @escaping (T) -> T) -> UnfoldSequence<T, T> {
    let nextState = { (state: inout T) -> T? in
        // Return `nil` if condition is no longer satisfied:
        guard condition(state) else { return nil }
        // Update current value _after_ returning from this call:
        defer { state = next(state) }
        // Return current value:
        return state
    }
    return sequence(state: first, next: nextState)
}

你可以把循环写成

let num = 1000
for i in sequence(first: 5, while: { num/$0 > 0 }, next: { $0 * 5 }) {
    print(i)
}

更简单的解决方案是while循环:

var i = 5
while num/i > 0 {
    print(i)
    i *= 5
}

但第一种解决方案的优点是循环变量的范围仅限于循环体,循环变量是常量。

Swift 3.1 将提供prefix(while:) method for sequences, 然后不再需要辅助函数:

let num = 1000
for i in sequence(first: 5, next: { $0 * 5 }).prefix(while: { num/$0 > 0 }) {
    print(i)
}

以上所有解决方案都与给定的C循环“等效”。 然而,如果num接近Int.max,它们都会崩溃 并且$0 * 5溢出。如果这是一个问题,那么你必须检查 如果$0 * 5在进行乘法之前适合整数范围

实际上,这使得循环更简单 - 至少如果我们假设那样 num >= 5以便循环至少执行一次:

for i in sequence(first: 5, next: { $0 <= num/5  ? $0 * 5 : nil }) {
    print(i)
}

答案 1 :(得分:1)

为了完整性:while循环方法的替代方法是使用AnyIterator

let num = 1000

var i = 5
for i in AnyIterator<Int>({
    return i <= num ? { defer { i *= 5 }; return i }() : nil
}) {
    // note that we choose to shadow the external i variable name,
    // such that any access to i within this loop will only refer
    // to the loop local immutable variable i.
    print(i)

    // e.g. i += 1 not legal, i refers to a constant here!

} /* 5 
     25 
     125 
     625 */

此方法与while循环具有相同的缺点,因为循环“外部”i变量在循环块的范围之外和之后存在。但是,此外部i变量不是可在循环体中访问的i变量,因为我们让循环体变量i影响外部变量,从而限制对{{}的访问1}}在body体内的不可变,临时(loop scope local)之一。