Swift 3 for循环增量

时间:2016-05-11 18:03:25

标签: swift swift3

如何在Swift3中编写以下内容?

$value->attribute == 'CUSTOMER'

这是我自己的尝试

for (f = first; f <= last; f += interval)          
{
    n += 1
}

5 个答案:

答案 0 :(得分:63)

Swift 2.2 - &gt; 3.0:Strideable:s stride(...)替换为全局stride(...)函数

在Swift 2.2中,我们可以(正如您自己尝试过的那样)使用蓝图(和默认实现)函数stride(through:by:)stride(to:by:) from the protocol Strideable

/* Swift 2.2: stride example usage */
let from = 0
let to = 10
let through = 10
let by = 1
for _ in from.stride(through, by: by) { } // from ... through (steps: 'by')
for _ in from.stride(to, by: by) { }      // from ..< to      (steps: 'by')

在Swift 3.0中,这两个函数已从Strideable中移除,而不是the global functions stride(from:through:by:) and stride(from:to:by:);因此上面的等效Swift 3.0版本为

/* Swift 3.0: stride example usage */
let from = 0
let to = 10
let through = 10
let by = 1
for _ in stride(from: from, through: through, by: by) { }
for _ in stride(from: from, to: to, by: by) { }

在您的示例中,您希望使用封闭间隔步幅替代stride(from:through:by:),因为for循环中的不变量使用的比较较少或等于({{1 }})。即。

<=

自然地,我们仅使用您的/* example values of your parameters 'first', 'last' and 'interval' */ let first = 0 let last = 10 let interval = 2 var n = 0 for f in stride(from: first, through: last, by: interval) { print(f) n += 1 } // 0 2 4 6 8 10 print(n) // 6 循环作为从for循环到for的段落的示例,您可以自然地为您的具体示例计算{ {1}}无需循环(stride)。

Swift 3.0:n替代更复杂的迭代增量逻辑

使用the implementation of evolution proposal SE-0094,Swift 3.0引入了全局n=1+(last-first)/interval函数:

对于具有更复杂迭代增量关系的情况(在本示例中不是这种情况),它可以是stride的适当替代。

  

<强>声明(S)

sequence

我们将简要介绍这两个功能中的第一个。 stride参数采用一个闭包,在给定当前序列元素(从func sequence<T>(first: T, next: @escaping (T) -> T?) -> UnfoldSequence<T, (T?, Bool)> func sequence<T, State>(state: State, next: @escaping (inout State) -> T?) -> UnfoldSequence<T, State> 开始)时,应用一些逻辑来延迟构造下一个序列元素。如果next永远不会返回first,则next返回nil时会终止序列,也会无效。

应用于上面的简单常量步长示例,next方法有点冗长并且过度杀伤w.r.t.适合此目的的nil解决方案:

sequence

stride函数对于具有非恒定步幅的情况非常有用,例如,如下面的Q&amp; A所述的例子:

请注意终止序列,最后let first = 0 let last = 10 let interval = 2 var n = 0 for f in sequence(first: first, next: { $0 + interval <= last ? $0 + interval : nil }) { print(f) n += 1 } // 0 2 4 6 8 10 print(n) // 6 返回(如果不是:&#34;无限&#34;元素生成),或者,当Swift 3.1到达时,将组合使用其懒惰生成使用sequence序列方法,如进化提案SE-0045中所述。后者适用于此答案的运行示例,使nil方法更简洁,明确包括元素生成的终止条件。

prefix(while:)

答案 1 :(得分:24)

使用Swift 4.2,您可以选择以下5个示例中的一个来解决您的问题。

#1。使用stride(from:to:by:)函数

let first = 0
let last = 10
let interval = 2

let sequence = stride(from: first, to: last, by: interval)

for element in sequence {
    print(element)
}

/*
prints:
0
2
4
6
8
*/

#2。使用sequence(first:next:)函数

let first = 0
let last = 10
let interval = 2

let unfoldSequence = sequence(first: first, next: {
    $0 + interval < last ? $0 + interval : nil
})

for element in unfoldSequence {
    print(element)
}

/*
prints:
0
2
4
6
8
*/

#3。使用AnySequence init(_:)初始值设定项

let anySequence = AnySequence<Int>({ () -> AnyIterator<Int> in
    let first = 0
    let last = 10
    let interval = 2

    var value = first
    return AnyIterator<Int> {
        defer { value += interval }
        return value < last ? value : nil
    }
})

for element in anySequence {
    print(element)
}

/*
prints:
0
2
4
6
8
*/

#4。使用CountableRange filter(_:)方法

let first = 0
let last = 10
let interval = 2

let range = first ..< last
let lazyCollection = range.lazy.filter({ $0 % interval == 0 })

for element in lazyCollection {
    print(element)
}

/*
prints:
0
2
4
6
8
*/

#5。使用CountableRange flatMap(_:)方法

let first = 0
let last = 10
let interval = 2

let range = first ..< last
let lazyCollection = range.lazy.compactMap({ $0 % interval == 0 ? $0 : nil })

for element in lazyCollection {
    print(element)
}

/*
prints:
0
2
4
6
8
*/

答案 2 :(得分:11)

简单地说,为Swift 3.0工作代码:

let (first, last, interval) = (0, 100, 1)
var n = 0
for _ in stride(from: first, to: last, by: interval) {
    n += 1
}

答案 3 :(得分:0)

我们还可以使用while循环作为替代方式

while first <= last {
    first += interval
}

答案 4 :(得分:-5)

for _ in 0.stride(to:last,by:interval)                 {                     n + = 1                 }