是否可以使用“yield”来生成“Iterator”而不是 Scala 中的列表?

2024-02-25

是否可以使用yield作为迭代器而不评估每个值?

当很容易实现复杂的列表生成时,这是一个常见的任务,然后你需要将其转换为Iterator,因为你不需要一些结果......


当然。实际上,非严格性有三种选择,我在下面列出。对于示例,假设:

val list = List.range(1, 10)
def compute(n: Int) = {
    println("Computing "+n)
    n * 2
}
  1. Stream. A Stream是一个惰性评估列表。它将根据需要计算值,但一旦计算完毕就不会重新计算值。如果您要多次重复使用流的某些部分,那么它是最有用的。例如,运行下面的代码将打印“Computing 1”、“Computing 2”和“Computing 3”各一次。

    val stream = for (n <- list.toStream) yield compute(n)
    val third = stream(2)
    println("%d %d" format (third, stream(2)))
    
  2. A view。视图是对基本集合的操作的组合。检查视图时,检查的每个元素都是按需计算的。如果您随机访问视图,但只会查看其中的一小部分,那么它是最有用的。例如,运行下面的代码将打印“Computing 3”两次,并且不会打印任何其他内容(好吧,除了结果之外)。

    val view = for (n <- list.view) yield compute(n)
    val third = view(2)
    println("%d %d" format (third, view(2)))
    
  3. Iterator. An Iterator是用来懒洋洋地浏览集合的东西。可以这么说,我们可以将其视为“一次性”收藏。它既不会重新计算也不会存储任何元素——一旦元素被“计算”,它就不能再次使用。因此,使用起来有点棘手,但考虑到这些限制,它是最有效的。例如,下面的例子需要有所不同,因为Iterator不支持索引访问(如果这样写,视图的性能会很差),下面的代码打印“计算1”,“计算2”,“计算3”,“计算4”,“计算5”和“计算6” ”。此外,它在末尾打印两个不同的数字。

    val iterator = for (n <- list.iterator) yield compute(n)
    val third = iterator.drop(2).next
    println("%d %d" format (third, iterator.drop(2).next))
    
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

是否可以使用“yield”来生成“Iterator”而不是 Scala 中的列表? 的相关文章

随机推荐