2015-10-14 49 views
-1

我有一个名为vertexDict一个文本文件,其中有由“\ 1”分裂多个键值对外界附加价值,我需要将其转换为一个地图在我的火花program.Here是我的代码:阶VAR未能获得foreach循环

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) 
    } 
}) 

问题是mapDict仍然foreach循环结束后空的,但我debuged进入循环,并mapDict成功添加元素到它,因此我通过绕过这个问题:

val mapDict = sc.textFile(vertexDict).map(line=> line.split("\1")).map(a=>a(0).toLong->a(1)).collect().toMap 

它的工作原理。但我仍然不知道为什么foreach未能添加。 谢谢!

+1

的' “\ 1”'不编译。你能粘贴实际的代码吗? – Jus12

+0

“\ 1”只是一个我使用的分隔符,可以是任何东西。这是我的实际代码,代码的其他部分是巨大的,并且对此问题没有任何影响。 – seabiscuit08

+0

您的需要mapDict是可变的附加价值给它 – Hackaholic

回答

0

似乎有一些问题,你的逻辑。正确的逻辑是:

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) 
0

这是一个相当迫切的问题解决办法。 FP方法是将其视为线的集合,从中想要生成从符合特定标准(此处为两项)的线获取的地图。尝试:

val str = "1234\1hello\nNonmatching line\n3456\1world\nAline\1with too\1many matches" 
val mapDict = str.lines.map(a => a.split("\1")).collect {case Array(k,v) => k->v}.toMap 

我添加了1条项目和3条项目来证明它们被过滤掉。这给出:

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

请注意,您不需要mapDict是一个var更多。

0

我终于知道为什么修改foreach循环的地图收集不起作用:因为火花运行并行和地图收集在不同的分区改变,我在我的问题粘贴的解决方案只需使用RDD操作收集得到所有分区数据到驱动程序并在本地运行到映射。 所以解决方法是使用火花累加器。