Monday, November 1, 2010

scalaでDir.glob("**/*.sql")

RubyだとDir.glob("**/*.sql")で指定したディレクトリから、
再帰的に*.sqlのファイルパスを検索してくれるが、
scalaには見当たらなかったので、書いてみた。

  // glob **/*.sql 
  val globSqlFiles = glob((f: File) => 
    !f.isDirectory && f.getName.endsWith(".sql")) _
  
  // curried function
  def glob(filter: (File) => Boolean)(dirs: List[String]): List[File] = {
    def recursive(dir: File, acc: List[File]): List[File] = 
      Option(dir.listFiles) match {
        case None => throw new FileNotFoundException(dir.getAbsolutePath)
        case Some(lists) => 
          val filtered = lists.filter{ c =>  filter(c) }.toList
          val childDirs = lists.filter{ c => c.isDirectory && !c.getName.startsWith(".") }
          return ( (acc ::: filtered) /: childDirs){ (a, dir) => recursive(dir, a)}
    }
    dirs.flatMap{ d => recursive(new File(d), Nil)}
  }

  // 使い方。対象ディレクトリはListで複数指定できる。
  globSqlFiles(List("/tmp/sql"))

汎用的になるようにカリー化してみた。
3、4行目の条件に正規表現を組み込めば曖昧検索できる。

S-99: Ninety-Nine Scala Problemsを頑張ってやっているせいか、
immutableなListの再帰に対してアレルギーがなくなってきた。

No comments:

Post a Comment