gpt4 book ai didi

Scala Lazy Collection 有人可以解释以下行为

转载 作者:行者123 更新时间:2023-12-04 15:52:38 26 4
gpt4 key购买 nike

我有一个普通列表并在其上定义了两个过滤器。我用第一个过滤器过滤列表,然后用下一个过滤器过滤输出并获取最后一个元素。

  1. 我正在对列表对象 lst (NORMAL LIST) 执行上述操作
  2. 我正在对 lst.view (LAZY LIST) 进行上述操作

第二个操作似乎需要更多的迭代。似乎在某一时刻重新开始了整个操作。请找到下面的代码。有人可以解释一下原因吗?

object SolutionTest {
val lst = List(("Mark", 32), ("Bob", 22), ("Jane", 8), ("Jill", 21),("Nick", 50), ("Nancy", 42), ("Mike", 19), ("Sara", 12), ("Paula", 42),("John", 21))
//> lst : List[(String, Int)] = List((Mark,32), (Bob,22), (Jane,8), (Jill,21),
//| (Nick,50), (Nancy,42), (Mike,19), (Sara,12), (Paula,42), (John,21))
lst.size //> res0: Int = 10

def filter1(tup:(String, Int)):Boolean={
println("from filter1 "+ tup)
val (_, age) = tup
age > 17
} //> filter1: (tup: (String, Int))Boolean

def filter2(tup:(String, Int)):Boolean={
println("from filter2 "+ tup)
val (name, _) = tup
name.startsWith("J")
} //> filter2: (tup: (String, Int))Boolean


//NORMAL LIST
lst.filter(filter1).filter(filter2).last //> from filter1 (Mark,32)
//| from filter1 (Bob,22)
//| from filter1 (Jane,8)
//| from filter1 (Jill,21)
//| from filter1 (Nick,50)
//| from filter1 (Nancy,42)
//| from filter1 (Mike,19)
//| from filter1 (Sara,12)
//| from filter1 (Paula,42)
//| from filter1 (John,21)
//| from filter2 (Mark,32)
//| from filter2 (Bob,22)
//| from filter2 (Jill,21)
//| from filter2 (Nick,50)
//| from filter2 (Nancy,42)
//| from filter2 (Mike,19)
//| from filter2 (Paula,42)
//| from filter2 (John,21)
//| res1: (String, Int) = (John,21)

//LAZY LIST
lst.view.filter(filter1).filter(filter2).last
//> from filter1 (Mark,32)
//| from filter2 (Mark,32)
//| from filter1 (Bob,22)
//| from filter2 (Bob,22)
//| from filter1 (Jane,8)
//| from filter1 (Jill,21)
//| from filter2 (Jill,21)
//| from filter1 (Mark,32) RESTARTING THE OPERATION HERE!!!
//| from filter2 (Mark,32)
//| from filter1 (Bob,22)
//| from filter2 (Bob,22)
//| from filter1 (Jane,8)
//| from filter1 (Jill,21)
//| from filter2 (Jill,21)
//| from filter1 (Nick,50)
//| from filter2 (Nick,50)
//| from filter1 (Nancy,42)
//| from filter2 (Nancy,42)
//| from filter1 (Mike,19)
//| from filter2 (Mike,19)
//| from filter1 (Sara,12)
//| from filter1 (Paula,42)
//| from filter2 (Paula,42)
//| from filter1 (John,21)
//| from filter2 (John,21)
//| res2: (String, Int) = (John,21)
}

最佳答案

在您的评论“RESTARTING HERE”之前的第一个操作来自寻找过滤序列中的第一个元素。 Scala 开始过滤,直到找到结果中的第一个元素 (Jill,21)。在此之后,它实际上开始处理整个序列。

发生这种情况是因为 lastimplementedTraversableLike 类中,如下所示:

def last: A = {
var lst = head
for (x <- this)
lst = x
lst
}

它在真正遍历序列之前调用 head。简单的 view 不使用缓存,所以在稍微过滤找到 head 之后,它必须重新启动。

View 上的其他函数可能无法表现出这种重新启动行为。例如 lst.view.filter(filter1).filter(filter2).lastOption 只运行一次序列。

关于Scala Lazy Collection 有人可以解释以下行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33720265/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com