将理解力转换为LazyList

问题描述

我有

  • 文件列表(filepaths
  • 一种读入并处理文件(loadData)的方法
  • 一种用于计算该文件统计信息的方法

仅当我们还需要计算统计信息时,我才想读取文件。下面的行将遍历文件路径,并返回其名称和文件内容。

for((name,path) <- filepaths) yield (name,loadData(path))

是否可以对LazyList进行这样的理解,以便对loadData部分进行懒惰的评估?

解决方法

for comprehension只是flatMapmap函数组合的语法糖。您可以使用地图功能来做到这一点:

def loadData(path: String): String = {
  println(s"launch loadData on $path")
  s"${path}_suffix"
}

val filePaths = Seq("p1" -> "path1","p2" -> "path2")
val lazyList = filePaths.to(LazyList).map{
  case (name,path) => name -> loadData(path)
}
println(lazyList)
println(lazyList.force)

// output will be:
//LazyList(<not computed>)
//launch loadData on path1
//launch loadData on path2
//LazyList((p1,path1_suffix),(p2,path2_suffix))

在这里我们看到loadData仅在需要下一个元素时才求值。

,

绝对有可能。

for ((name,path) <- filepaths) yield (name,loadData(path))

只是语法糖

filepaths.map { x =>
  val (name,path) = x
  (name,loadData(path)
}

(这可能不是编译器实际要解决的(我忘记了是否会有多个函数(一个提取对,一个调用loadData))

由于map上有一个LazyList,因此如果filepathsLazyList,它将起作用。

也就是说,这并不是最大程度的懒惰:获取第n个条目需要评估第(n - 1)个条目。

当然,只要您有Seq[(A,B)](或Iterable[(A,B)] / Traversable[(A,B)]),就值得考虑您真正想要的是Function1[A,B]还是{{1 }}(可以认为是构建Map[A,B]的子集的简单方法)。

Function[A,B]

(请注意,// assuming that filepaths is an `Iterable[(A,B)]` filepaths.toMap.mapValues(loadData(_)) 可以省略)。

这将是非严格的(在您查找给定的(_)之前不会调用loadData),但是它不会是最大程度的懒惰(没有任何备注:每次查找都会导致name通话)。如果您想要最大程度的懒惰,则必须实现自己的备忘录。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...