提取RDD中列表的元素

时间:2016-10-19 13:45:32

标签: scala apache-spark

我想要实现的目标

我正在使用Spark和Scala。我有两个配对RDD。

rdd1 : RDD[(String, List[String])]
rdd2 : RDD[(String, List[String])]

两个RDD都以第一个值连接在一起。

val joinedRdd = rdd1.join(rdd2)

因此生成的RDD的类型为RDD[(String, (List[String], List[String]))]。我想映射这个RDD并提取两个列表的元素,以便生成的RDD只包含这两个列表中的这些元素。

实施例

rdd1 (id, List(a, b))
rdd2 (id, List(d, e, f))
wantedResult (a, b, d, e, f)

天真的方法

我天真的方法是直接使用(i)添加每个元素,如下所示:

val rdd = rdd1.join(rdd2)
    .map({ case (id, lists) => 
        (lists._1(0), lists._1(1), lists._2(0), lists._2(2), lists._2(3)) })

/* results in RDD[(String, String, String, String, String)] */

有没有办法获取每个列表的元素,而不是单独解决每个列表?类似于" lists._1.extractAll"。有没有办法使用flatMap来实现我想要实现的目标?

1 个答案:

答案 0 :(得分:4)

您可以使用++运算符简单地连接两个列表:

val res: RDD[List[String]] = rdd1.join(rdd2)
  .map { case (_, (list1, list2)) => list1 ++ list2 }

可能更好的方法是避免携带可能非常大的List[String],将RDD分解为较小的(键值)对,将它们连接起来,然后执行groupByKey:< / p>

val flatten1: RDD[(String, String)] = rdd1.flatMapValues(identity)
val flatten2: RDD[(String, String)] = rdd2.flatMapValues(identity)
val res: RDD[Iterable[String]] = (flatten1 ++ flatten2).groupByKey.values