Scala - 嵌套循环,for-comprehension和最终迭代的类型

时间:2012-02-06 14:47:25

标签: scala loops

我对scala相对较新,并成功制作了一些非常简单的程序。 然而,现在我正在尝试一些现实世界的问题解决方案,事情变得有点困难......

我想将一些文件读入'Configuration'对象,使用各种'FileTypeReader'子类型,可以'接受'某些文件(每个FileTypeReader子类型一个),如果可以从中提取配置,则返回Option [Configuration]

我正在努力避免命令式的风格,例如写下这样的东西(使用scala-io,scaladoc for Path here http://jesseeichar.github.com/scala-io-doc/0.3.0/api/index.html#scalax.file.Path):

(...)
trait FileTypeReader {
   import scalax.file.Path
   def accept(aPath : Path) : Option[Configuration]
}
var readers : List[FileTypeReader] = ...// list of concrete readers
var configurations = for (
          nextPath <- Path(someFolder).children();
          reader <- readers
      ) yield reader.accept(nextPath);
(...)

当然,这不起作用,for-comprehensions返回第一个生成器类型的集合(这里是一些IterablePathSet)。

既然我尝试了很多变种并且觉得自己喜欢在圈子里跑,那我就乞求你这个问题的建议来解决我的问题? - 优雅的问题! :)

非常感谢,

SNI。

2 个答案:

答案 0 :(得分:4)

如果我理解正确,您的问题是您有一个Set[Path],并且希望产生一个List[Option[Configuration]]。如上所述,configurations将是Set[Option[Configuration]]。要将其更改为List,请使用toList方法,即

val configurations = (for {
    nextPath <- Path(someFolder).children
    reader   <- readers
  } yield reader.accept(nextPath) ).toList

或者,更改生成器本身的类型:

val configurations = for {
    nextPath <- Path(someFolder).children.toList
    reader   <- readers
  } yield reader.accept(nextPath)

你可能真的想得到一个List[Configuration],你可以优雅地做到Option是一个monad:

val configurations = for {
    nextPath <- Path(someFolder).children.toList
    reader   <- readers
    conf     <- reader.accept(nextPath)
  } yield conf

答案 1 :(得分:0)

您是否正在尝试找到可以提取的第一个配置?如果没有,如果返回多个配置会发生什么?

在第一种情况下,我只是得到for-comprehension的结果并在其上调用find,这将返回Option