如何在键值对中找到公共值并将其作为值放在所有对中?

时间:2018-04-26 21:06:12

标签: scala apache-spark key-value

如何获取键值对中的值的交集?

我有成对:

  

(p, Set(n))

我使用reduceByKey并最终得到:

  

(p1, Set(n1, n2)) (p2, Set(n1, n2, n3)) (p3, Set(n2, n3))

我想要的是找到所有对中存在的n并将它们作为值。对于上述数据,结果将通过

  

(p1, Set(n2)) (p2, Set(n2)), (p3, Set(n2))

只要我搜索,就没有火花中的reduceByValue。唯一似乎更接近我想要的功能是reduce(),但它没有用,因为结果只有一个键值对((p3, Set(n2)))

有什么办法可以解决吗?或者我应该从一开始就想到其他什么?

代码:

val rRdd = inputFile.map(x => (x._1, Set(x._2)).reduceByKey(_++_)

val wrongRdd  = rRdd.reduce{(x, y) => (x._1, x._2.intersect(y._2))}

我可以看到为什么wrongRdd不正确,我只是想说明(p3, Set(n2))是如何产生的。

1 个答案:

答案 0 :(得分:2)

您可以先将reduce设置到其交叉点(例如s),然后将(k, v)替换为(k, s)

val rdd = sc.parallelize(Seq(
  ("p1", Set("n1", "n2")),
  ("p2", Set("n1", "n2", "n3")),
  ("p3", Set("n2", "n3"))
))

val s = rdd.map(_._2).reduce(_ intersect _)
// s: scala.collection.immutable.Set[String] = Set(n2)

rdd.map{ case (k, v) => (k, s) }.collect
// res1: Array[(String, scala.collection.immutable.Set[String])] = Array(
//   (p1,Set(n2)), (p2,Set(n2)), (p3,Set(n2))
// )