试图从文本文件中的行创建映射[String,String],不断出现错误

试图从文本文件中的行创建映射[String,String],不断出现错误,string,scala,dictionary,String,Scala,Dictionary,大家好,我正在尝试基于文本文件创建一个映射[String,String],在文本文件中有以“;;”开头的任意行,我用函数忽略这些行,而我不忽略的行是key->value。它们之间有2个空格 每当我运行代码时,我都会收到一个错误,说期望的类型映射[String,String]不是必需的类型,即使我的转换看起来是正确的 def createMap(filename: String): Map[String,String] = { for (line <- Source.fromFile

大家好,我正在尝试基于文本文件创建一个映射[String,String],在文本文件中有以“;;”开头的任意行,我用函数忽略这些行,而我不忽略的行是key->value。它们之间有2个空格

每当我运行代码时,我都会收到一个错误,说期望的类型映射[String,String]不是必需的类型,即使我的转换看起来是正确的

def createMap(filename: String): Map[String,String] = {
    for (line <- Source.fromFile(filename).getLines) {
      if (line.nonEmpty && !line.startsWith(";;;")) {
        val string: String = line.toString
        val splits: Array[String] = string.split("  ")
        splits.map(arr => arr(0) -> arr(1)).toMap
      }
    }
  }
def createMap(文件名:String):Map[String,String]={
对于(行arr(0)->arr(1)).toMap
}
}
}

我希望它返回一个(String->String)映射,但是我得到了一堆错误。如何修复此问题?

因为if语句不是for循环中的表达式。在生成结果时,应该使用if作为过滤器。要返回结果,您必须将其设置为一个可供理解的选项。理解后过滤结果。可以将此结构映射到地图

import scala.io.Source
def createMap(filename: String): Map[String,String] = {
  val keyValuePairs = for (line <- Source.fromFile(filename).getLines; if line.nonEmpty && !line.startsWith(";;;")) yield {
      val string = line.toString
      val splits: Array[String] = string.split("  ")
      splits(0) -> splits(1)
  }
  keyValuePairs.toMap
}

您正在声明一个函数,该函数应返回
映射[String,String]
,但您的实现只返回
单元
(此外,您没有创建任何映射)。在java或C++的意义下,Scala实际上并没有< <代码> >,它只是调用“<代码>前缀< /C> >方法的语法糖,返回<代码>单元< />代码(这是您在这里所做的)。或者对于
map
flatMap
filter
(可用于返回实际地图)的嵌套调用。请参见&。哦,好的,那么我如何更改它,使它实际返回一个映射?您只需要使用正确的语法(使用
yield
),我相信如果您阅读这两个链接,您将使它工作;)顺便说一句,我从昨天起就记得你。我刚刚注意到,我之前的回答有一个错误,即为值分割键的是两个空格(而不是一个空格),因此分割的数组将始终有两个元素。我会马上用修正更新我以前的答案。如果这让你一直在找麻烦,在那里或这里提问(如果你相信Ameritate提供了另一个答案)。是的,我记得你的评论非常有用,但出于某种原因,它没有返回文本文件中的每个值,有些值丢失了。作为参考,这里是文本飞行,如果你想自己测试它,看看它是否与你一样,以确保它不仅是我。有些单词完全缺失/不完整,这就是为什么我试着做上述操作,看看是否可以使用你推荐的方法来提出自己的解决方案,同时删除D�J� D EY2 JH AA1当你下载文本文件时,它是一个损坏的字符串谢谢,这类工作也很好,仍然会遇到缺少值的问题。由于缺少值,你的意思是地图正在填充空字符串吗??如果是这样的话,可能会在空白处拆分
val string=line.split(\\s+”)
没有任何键,完全缺少键,这是我运行此操作时正在解析的文本文件我有一个大小为133855的映射,它似乎是没有键的行的行计数;;;一开始我不确定这是否是您想要对这些值执行的操作,但您可以在每种情况下操纵拆分,因此看起来您是对的,文件中有一个损坏的文本!我刚刚删除了它,现在这个功能运行得很好,非常感谢。这确实是一次学习的经历。
import java.nio.charset.CodingErrorAction
import scala.io.{Codec, Source}

def createMap(filename: String): Map[String,String] = {
  val decoder = Codec.UTF8.decoder.onMalformedInput(CodingErrorAction.IGNORE)
  Source.fromFile(filename)(decoder).getLines()
    .filter(line => line.nonEmpty && !line.startsWith(";;;"))
    .flatMap(line => {
      val arr = line.split("\\s+")
      arr match {
        case Array(key, value) => Some(key -> value)
        case Array(key, values@_*) => Some(key -> values.mkString(" "))
        case _ => None
      }
    }).toMap
}