RDD中的MapValues和爆炸

时间:2016-08-17 20:34:02

标签: scala apache-spark

我在下面有这个示例RDD(下面称为rdd)。数据集是(String, Int)

的元组
(some | random | value, 10)
(some | random | value, 11)
(some | random | value, 12)

我想得到这个输出:

(some, 10)
(random, 10)
(value, 10)
(some, 11)
(random, 11)
(value, 11)
(some, 12)
(random, 12)
(value, 12)

我有这个Scala代码来尝试上述转换:

rdd.map(tuple => tuple._1.split("|").foreach(elemInArray => (elemInArray, tuple._2)))

在这段代码中,我遍历整个数据集,并将元组的第一部分拆分为|。然后我遍历split返回的数组中的每个元素,并创建一个元组,每个element和我从tuple._1获得的计数。

出于某种原因,我不断得到这个结果:

()
()
()
()
()
()
()
()
()

有谁知道这个问题?我似乎无法找到我出错的地方。

1 个答案:

答案 0 :(得分:4)

您实际上需要使用flatMap

val lt = List(("some | random | value", 10),
              ("some | random | value", 11),
              ("some | random | value", 12))

val convert: ((String, Int)) => List[(String, Int)] = tuple => tuple._1.split('|').map(str =>
  (str, tuple._2)).toList

val t = lt.flatMap(convert)

正如我们所看到的,定义convert函数非常有用,因为我们可以通过将该函数传递给单个元素来确保正确处理每个元素。然后,我们可以将同一个函数传递给flatMap,这会将convert生成的结果列表聚合到一个列表中。

以上产量:

t: List[(String, Int)] = List((some ,10), 
                              ( random ,10), 
                              ( value,10), 
                              (some ,11), 
                              ( random ,11), 
                              ( value,11), 
                              (some ,12), 
                              ( random ,12),
                              ( value,12))

显然,我没有费心去处理结果中的额外空白字符,但是使用convert更新trim函数可以轻松解决这个问题:

val convert: ((String, Int)) => List[(String, Int)] = tuple => tuple._1.split('|').map(str =>
  (str.trim, tuple._2)).toList