swift第三方库 - 用动态范围表示快速循环
ios音频播放库 (2)
...或者如何在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个块。
有任何想法吗?
谢谢
为了完整性:
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
影响外部变量,将对体内
i
访问限制为不可变的临时变量(循环范围局部)一。
使用辅助函数(最初定义为 转换C风格的循环,该循环使用除了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:)
方法
,然后不再需要辅助函数:
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)
}