scala变量无法在foreach循环外部获取附加值

scala变量无法在foreach循环外部获取附加值,scala,foreach,apache-spark,Scala,Foreach,Apache Spark,我有一个名为vertexDict的文本文件,它有多个由“\1”分割的键值对,我需要在spark程序中将其转换为映射。以下是我的代码: var mapDict = Map[Long, String]() sc.textFile(vertexDict).map(line=> line.split("\1")).foreach(a=>{ if(a.length ==2 ){ mapDict += a(0).toLong->a(1) } }) 问题是,在foreach

我有一个名为vertexDict的文本文件,它有多个由“\1”分割的键值对,我需要在spark程序中将其转换为映射。以下是我的代码:

var mapDict = Map[Long, String]()
sc.textFile(vertexDict).map(line=> line.split("\1")).foreach(a=>{
  if(a.length ==2 ){
    mapDict += a(0).toLong->a(1)
  }
})
问题是,在foreach循环结束后,mapDict仍然为空,但我调试到了该循环中,并且mapDict成功地将元素添加到该循环中;因此,我通过以下方式绕过这个问题:

val mapDict = sc.textFile(vertexDict).map(line=> line.split("\1")).map(a=>a(0).toLong->a(1)).collect().toMap
但我仍然不知道为什么foreach没有添加。
谢谢

您的逻辑似乎有问题。正确的逻辑是:

var mapDict = Map[Long, String]()
val str = "1234\1hello\n3456\1world"
str.lines.foreach{line => 
  val a = line.split("\1")
  if(a.length == 2) {
    mapDict += (a(0).toLong->a(1))
  }
}
以下是输出:

scala> mapDict foreach println
(1234,hello)
(3456,world)

这是解决这个问题的一个相当必要的办法。FP方法是将其视为一个行集合,您希望从中生成一个映射,该映射取自符合特定条件的行(这里有两个项)。尝试:

我添加了一个1项行和3项行,以证明它们已被过滤掉。这使得:

mapDict: scala.collection.immutable.Map[String,String] = Map(1234 -> hello, 3456 -> world)

请注意,您不再需要将mapDict映射为var。

我终于知道为什么在foreach循环中修改Map集合不起作用了:因为spark并行运行,并且Map集合在不同的分区中更改,我在问题中粘贴的解决方案只是使用rdd操作collect将所有分区数据获取到驱动程序并在本地运行toMap。
因此,解决方法是使用火花蓄能器。

“\1”
无法编译。你能粘贴实际的代码吗?\1“只是我使用的一个delimeter,可以是任何东西。这是我的实际代码,代码的其他部分非常庞大,并且与此问题无关。你需要mapDict可变以向iti附加值,这还不够吗?我应该怎么做?将其设为scala.collection.mutable.Map[Long,String]()
mapDict: scala.collection.immutable.Map[String,String] = Map(1234 -> hello, 3456 -> world)