arrays - 为什么以及何时在 Swift 中对数组使用惰性?

标签 arrays swift lazy-evaluation

[1, 2, 3, -1, -2].filter({ $0 > 0 }).count // => 3

[1, 2, 3, -1, -2].lazy.filter({ $0 > 0 }).count // => 3

在第二个语句中添加lazy 有什么好处。根据我的理解,当使用 lazy 变量时,内存会在使用时初始化为该变量。它在这种情况下有何意义?

enter image description here

尝试更详细地了解 LazySequence 的使用。我曾在序列上使用过 mapreducefilter 函数,但从未在 lazy 序列上使用过。需要了解为什么要使用它?

最佳答案

lazy 改变数组的处理方式。当不使用 lazy 时,filter 处理整个数组并将结果存储到一个新数组中。当使用 lazy 时,序列或集合中的值是按需从下游函数生成的。这些值不存储在数组中;它们只在需要时生产。

考虑这个修改后的示例,我在其中使用了 reduce 而不是 count 以便我们可以打印出正在发生的事情:

不使用lazy:

在这种情况下,将首先过滤所有项目,然后再计算任何内容。

[1, 2, 3, -1, -2].filter({ print("filtered one"); return $0 > 0 })
    .reduce(0) { (total, elem) -> Int in print("counted one"); return total + 1 }
filtered one
filtered one
filtered one
filtered one
filtered one
counted one
counted one
counted one

使用lazy:

在这种情况下,reduce 要求计算一个项目,filter 会一直工作直到找到一个,然后 reduce 会询问对于另一个,filter 将一直工作,直到找到另一个。

[1, 2, 3, -1, -2].lazy.filter({ print("filtered one"); return $0 > 0 })
    .reduce(0) { (total, elem) -> Int in print("counted one"); return total + 1 }
filtered one
counted one
filtered one
counted one
filtered one
counted one
filtered one
filtered one

何时使用lazy:

选项-clicking on lazy给出了这样的解释:

pop-up for lazy in Xcode

来自 lazy讨论:

链接操作时使用惰性属性:

  1. 防止中间操作分配存储空间

  2. 当您只需要最终集合的一部分以避免不必要的计算时

    我会添加第三个:

  3. 当您希望下游流程更快开始而不必等待上游流程先完成所有工作时

因此,例如,如果您正在搜索第一个正 Int,则您希望在 filter 之前使用 lazy,因为一旦找到一个,搜索就会停止,这样 filter 就不必过滤整个数组,也不必为过滤后的数组分配空间。

对于第 3 点,假设您有一个程序显示 1...10_000_000 范围内的质数,并在该范围内使用 filter。您宁愿在找到素数时显示它们,也不愿在显示任何内容之前等待计算完所有素数。

关于arrays - 为什么以及何时在 Swift 中对数组使用惰性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51917054/

相关文章:

ios - 如何将角标(Badge)添加到 UINavigationItem (UIBarButtonItem) - Swift 3

haskell - 为什么我的函数不适用于无限列表?

c# - 某处有 Ix.NET (System.Interactive) 的示例吗?

javascript - 按属性对列表进行排序并在 JavaScript 中每个首字母更改之前添加一个对象

python - 什么时候获取 numpy 数组的子矩阵返回 View 而不是复制?

arrays - 如何在 Go 中的 slice 或结构中存储不同的结构(不嵌入)

ios - 在每个 ViewController 的顶部添加 subview

ios - FBSDKLog : FBSDKGraphRequestConnection cannot be started before Facebook SDK initialized

loops - 在 Haskell 中融合多重折叠

javascript - 如何对这个 javascript 对象进行排序?