在 swift 中表达具有动态范围的 for 循环

2023-12-07

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

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

如果我写这个

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 个块,而不是如果我是:5、25、125 等。

有任何想法吗?

Thanks


使用辅助函数(最初定义于将使用除法作为步骤的 C 风格 for 循环转换为 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
}

但第一种方案的优点是循环变量的作用域仅限于循环体,并且循环变量是一个常量。

斯威夫特3.1将提供一个prefix(while:)序列方法, 然后辅助函数就不再需要了:

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

所有上述解决方案都“等效于”给定的 C 循环。However,如果出现以下情况,它们都会崩溃num接近Int.max and $0 * 5溢出。如果这是一个问题,那么你必须检查 如果$0 * 5适合整数范围before做乘法。

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

for i in sequence(first: 5, next: { $0 <= num/5  ? $0 * 5 : nil }) {
    print(i)
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 swift 中表达具有动态范围的 for 循环 的相关文章

随机推荐