はい、それほど簡潔ではありませんが、次のようになります。
import java.io.File
import scala.io.Source
for {
file <- new File(dir).listFiles.toIterator if file.isFile
line <- Source fromFile file getLines
} { doSomething line }
秘訣はflatMap
、その理解のfor
構文糖衣です。たとえば、上記は多かれ少なかれ次と同等です。
new File(dir)
.listFiles.toIterator
.filter(_.isFile)
.flatMap(Source fromFile _ getLines)
.map(doSomething)
Daniel Sobralが以下のコメントで述べているように、このアプローチ(およびあなたの質問のコード)はファイルを開いたままにします。これが1回限りのスクリプトである場合、またはREPLで作業しているだけの場合、これは大したことではないかもしれません。問題が発生した場合は、pimp-my-libraryパターンを使用して、基本的なリソース管理を実装できます。
implicit def toClosingSource(source: Source) = new {
val lines = source.getLines
var stillOpen = true
def getLinesAndClose = new Iterator[String] {
def hasNext = stillOpen && lines.hasNext
def next = {
val line = lines.next
if (!lines.hasNext) { source.close() ; stillOpen = false }
line
}
}
}
今すぐ使用Source fromFile file getLinesAndClose
すれば、ファイルが開いたままになることを心配する必要はありません。