如何使用Stream在Scala中遍历树?

时间:2017-01-05 00:44:56

标签: scala stream

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

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。)

1 个答案:

答案 0 :(得分:2)

正如评论中所提到的,您基本上可以像处理Stream一样处理List,并且您将获得所需的延迟评估序列。你的解决方案:

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)