2017-03-03 11 views
0

我需要在Scala中地图或的foreach操作者改变一个外部变量,代码是如下:如何在Scala中更改map或foreach运算符中的外部变量?

val data = sc.textFile(inputFile) 
var examMap = Map[String, Int]() 
data.map(sample => { 
    if (examMap.contains(sample)) { 
     val value = examMap.get(sample).get 
     examMap -= sample 
     examMap += (sample -> (value + 1)) 
    } 
    else { 
     examMap += (sample -> 1) 
    } 
}) 
+1

什么是你的问题有关shared variables? – Phasmid

+0

它闻起来可以用'foldLeft'或者自定义递归替换的可变性 – cchantep

+0

你可以编辑问题来包含一个可以适用于每个人的最小自包含示例,并说明它的意外结果是什么? – stefanobaghino

回答

1

一个版本与不可变的值,在这里我们为每个sample发生一个元组,组由样本标识和总和up通用样品之前我们转换tupled样品和数到Map[String,Int]

val data = sc.textFile(inputFile) 

val examMap = data.map(sample => (sample, 1)).reduceByKey(_+_).toMap 
1

@echo是正确的。他们的解决方案应该做你期望的。

还要说明一点:

与你(currrent)解决方案的问题是,如果你运行这个程序是一个真正的集群环境中(不--master local[*]),该map(和其他星火运营商)内部的功能被执行在完整数据集的一部分上并行处理不同的工作人员。因此,每个在其分区上执行map(或foreach)的工作人员也将收到要写入的examMap的副本。

最初,这张地图是空的,工作人员将更新他们的本地副本。最后,当分布式处理完成时,控制权将返回给驱动程序(您的程序)。但是,在这里使用examMap的原始副本 - 并且由于所有工作人员都更新了本地副本,因此此地图将为空。

尽管所示的方案是正确的,要走的路,你可能需要阅读的火花

相关问题