Как найти общие значения в парах ключ-значение и поместить их в качестве значения во все пары? - PullRequest
0 голосов
/ 27 апреля 2018

Как я могу получить пересечение значений в парах ключ-значение?

У меня есть пары:

(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 голосов
/ 27 апреля 2018

Вы можете сначала 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))
// )
...