2017-01-05 7 views
0

У меня есть простая файловая система абстракция:Как я могу использовать Stream для пересечения дерева в Scala?

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 

Проходя через дерево, как это было бы круто, но я не понимая, как создать Поток для этого из скаладока.

(я знаю, что могу просто написать простую рекурсивную функцию, но я пытаюсь обращал внимания на потоки здесь.)

+0

Вы можете в значительной степени лечить 'Stream' (или' Iterator') так же, как Вы были бы 'list', и последующие элементы будут вычислены лениво. EDIT: хороший учебник: http://alvinalexander.com/scala/how-to-use-stream-class-lazy-list-scala-cookbook – spiffman

ответ

1

Как уже упоминалось в комментариях, вы можете существенно лечить Stream так же, как вы бы List и вы получите желаемую лениво оцененную последовательность. Ваше решение:

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

Обратите внимание на flatMap, чтобы избежать создания Stream из Stream экземпляров.

Тест:

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) 

 Смежные вопросы

  • Нет связанных вопросов^_^