过滤和减少惰性结构

Filtering and reducing lazy structures

我想 filter 一个惰性结构,然后 reduce 它使用 Swift 语言。

func main() -> () {
    let result = (1...)
        .lazy
        .filter { [=10=] < 3 }
        .reduce(0, {[=10=] + })
    return print(
        result
    )
}

main()

这段代码可以编译;然而,该程序没有以正确的方式执行(花费太长时间)。屏幕上的打印结果应该是3。 有没有办法实现这个目标?

要使程序终止,您需要在原始序列上添加上限 (1...)

如上所示,您有一个无限的数字序列,从 1 开始。下面的运算符——尤其是 filter——无法“知道”它们一旦通过 3 就可以丢弃序列的其余部分。他们必须处理 整个无限序列 ,过滤掉除前两个元素之外的所有元素,然后 reduce 才能产生最终结果并打印出来。 (实际上,你最终会溢出 Int,所以程序会终止,但这并不是一件值得依赖的好事。)

如果您不想更改原来的 (1...),您可以通过将 filter 换成 prefix 来近似相同的行为。过滤器必须查看每个元素;前缀可以“知道”它在一定数量的元素之后停止。例如,这运行得非常快并打印出 3:

let result = (1...)
    .lazy
    .prefix(2)
    .reduce(0) {[=10=] + }

问题不是你的序列是惰性的,而是你的序列是无限的。您可能正在寻找 sequence 方法。示例:

let s = sequence(first: 0) {
    [=10=] > 3 ? nil : [=10=] + 1
}
let result = s.reduce(0) { [=10=] +  }
print(result) // 10

slazy 并且 可能 无限但 实际上 不是无限的,因为生成的方法该系列中的下一项通过在序列超过 3 时返回 nil 来提前退出。这类似于您的 filter 除了它不是过滤器,它是一个塞子。您可以在此处使用您喜欢的任何条件来生成塞子。