String 从字符串文件创建Scala映射的最有效方法是什么?

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()) {

现在,我正在尝试从csv文件创建一个
映射[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