...或者如何在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等。
有任何想法吗?
谢谢
最佳答案
使用辅助函数(最初在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)
}
关于swift - 快速显示动态范围的循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57359941/