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




swift3