现在,我正在尝试从csv文件中创建一个Map[String, String]
,其中单词是 Key * ,发音是 Value 。我已经使用下面的代码成功做到了。
def mapFile(filename: String): Map[String, String] = {
var content: String = ""
val file: BufferedSource = Source.fromFile(filename)
for (line <- file.getLines()) {
if (!line.contains("//")) {
content = content + line + "//"
}
}
content.split("//").map(_.split(" ")).map(arr => arr(0) -> arr(1)).toMap
}
因此,文件读取了文本文件,并且为文本文件中非//
的每一行创建了一个字符串,然后将该字符串拆分为键值,密钥被{{1}拆分},并用`“ //”``分隔值。
但是,它太慢了。
我有没有更有效的方法来创建地图,而无需花费5分钟?
答案 0 :(得分:2)
我相信您的主要问题是,您正在将所有文件读入 String ,以便在以后对其进行重新处理。这意味着,您不仅分配了两次所需的内存,而且还对文件进行了处理两次。
您可能对代码进行的第一个改进就是只需一个迭代即可完成所有操作。
import scala.io.Source
def mapFile(filename: String): Map[String, String] =
(for {
line <- Source.fromFile(filename).getLines
if (line.nonEmpty && !line.startsWith(";;;"))
Array(word, pronunciation) = line.split(" ")
} yield word -> pronunciation).toMap
上面的代码等效于(并将简化为类似的内容):
import scala.io.Source
def mapFile(filename: String): Map[String, String] =
Source
.fromFile(filename)
.getLines
.filter(line => line.nonEmpty && !line.startsWith(";;;"))
.map(line => line.split(" "))
.map { case Array(word, pronunciation) => word -> pronunciation }
.toMap
此外,如果输入文件太大,则可以查看FS2或Akka-Streams或任何其他类型的流来处理文件块。