String 从字符串文件创建Scala映射的最有效方法是什么?
现在,我正在尝试从csv文件创建一个String 从字符串文件创建Scala映射的最有效方法是什么?,string,scala,dictionary,String,Scala,Dictionary,现在,我正在尝试从csv文件创建一个映射[String,String],其中单词是键*,发音是值。我已经设法用下面的代码自己做了 def mapFile(filename: String): Map[String, String] = { var content: String = "" val file: BufferedSource = Source.fromFile(filename) for (line <- file.getLines()) {
映射[String,String]
,其中单词是键*,发音是值。我已经设法用下面的代码自己做了
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
}
def映射文件(文件名:String):映射[String,String]={
var content:String=“”
val文件:BufferedSource=Source.fromFile(文件名)
对于(行arr(0)->arr(1)).toMap
}
因此,文件读取文本文件,对于文本文件中不是/
的每一行,它创建一个字符串,然后将字符串拆分为键值,键值按“
拆分,值按“/”拆分
但是,它太慢了。有没有一种更有效的方法可以在不花费5分钟的情况下创建地图?我相信您的主要问题是,您正在将所有文件读入一个字符串中,然后重新处理它。这意味着,不仅要分配两次所需的内存,还要处理两次文件 对代码所做的第一个改进是在一次迭代中完成所有工作
此外,如果输入文件太大,您可以查看、或任何其他类型的流式处理,以逐块处理文件。
if(ok==false)
与if(!line.contains(;;;))
相同。选择第二个,它更有意义。你是一个天才,这工作非常出色,从5分钟到5秒。谢谢,在after-Array中到底发生了什么?@fucksy如果你指的是Array(单词,发音@*)
,那只是模式匹配,它的意思是(粗略地说):我们知道split的输出是一个数组,我们确信至少会有两个元素(假设您的文件中的所有单词都至少有一个教学大纲,这有点道理)因此,我们将取出第一个,并将其命名为word
,其余的将按顺序取出,我们称之为发音
,希望现在更清楚。@user11039395编辑了答案:修复了错误并添加了代码的“去糖化”形式。
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