…或者如何在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等。
有任何想法吗?
谢谢
使用辅助函数(最初在将使用除法的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函数:
prefix(while:)
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
Int.max
$0 * 5
实际上,这使循环更简单–至少如果我们假设 num >= 5这样,则循环至少执行一次:
num >= 5
for i in sequence(first: 5, next: { $0 <= num/5 ? $0 * 5 : nil }) { print(i) }