【问题标题】:How can I use Stream to traverse a tree in Scala?如何使用 Stream 在 Scala 中遍历树?
【发布时间】:2017-01-05 00:44:55
【问题描述】:

我有一个简单的文件系统抽象:

trait PathItem { val label: String }

case class PathEnd(label: String, uri: String) extends PathItem

case class PathDirectory(
  label: String = "", 
  contents: List[PathItem] = List.empty[PathItem]
) extends PathItem

通过这种结构,我可以构建任意复杂的子目录 (PathDirectory) 和文件 (PathEnd) 树。

我如何使用 Scala Streams 来提取“文件”列表,如下所示:

getFileStream( rootDir ).foreach( f => println(f.uri) )
getFileStream( rootDir ).find( _.uri == "someTargetURI" )

// where getFileStream creates a Stream[PathEnd] given a starting rootDir

像这样穿过树会有点酷,但我不明白如何从 scaladoc 中为此创建 Stream。

(我知道我可以只写一个简单的递归函数,但我想在这里了解 Streams。)

【问题讨论】:

  • 您几乎可以像对待 List 一样对待 Stream(或 Iterator),随后的元素将被延迟计算。编辑:一个很好的入门:alvinalexander.com/scala/…

标签: scala stream


【解决方案1】:

如 cmets 中所述,您基本上可以像对待 List 一样对待 Stream,并且您将获得所需的惰性评估序列。您的解决方案:

def fileStream(p: PathItem): Stream[PathEnd] = {
    p match {
        case pe: PathEnd => Stream(pe)
        case pd: PathDirectory => pd.contents.toStream.flatMap(fileStream)
    }
}

注意flatMap 以避免创建StreamStream 实例。

测试:

scala> val pd = PathDirectory(root,List(
    PathDirectory("src",List(PathDirectory("main",List(PathEnd("file.scala","file.uri"))))),
    PathDirectory("test",List(PathDirectory("main",List(PathEnd("test.scala","test.uri")))))))
scala> fileStream(pd).foreach(println)

PathEnd(file.scala,file.uri)
PathEnd(test.scala,test.uri)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-29
    • 1970-01-01
    • 1970-01-01
    • 2016-09-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多