一尘不染

快速表达动态范围的循环

swift

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

大家好,因为我们在Swift 3中没有使用c风格的循环,所以我似乎找不到一种表达一些复杂的循环的方法,所以也许您可以帮我一下。

如果我要写这个

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

快速3我该怎么做?

我的关闭时间是:

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

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

有任何想法吗?

谢谢


阅读 264

收藏
2020-07-07

共1个答案

一尘不染

使用辅助函数(最初在将使用除法的C样式for循环转换为Swift3时定义

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:)sequence方法,然后不再需要helper函数:

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)
}
2020-07-07