Значение сглаживания в парном RDD в искре

У меня есть парная RDD, которая выглядит как

(a1, (a2, a3))
(b1, (b2, b3))
...

Я хочу сгладить значения, чтобы получить

(a1, a2, a3)
(b1, b2, b3)
...

В настоящее время я делаю

rddData.map(x => (x._1, x._2._1, x._2._2))

Есть ли лучший способ выполнить преобразование? Вышеупомянутое решение становится уродливым, если value содержит много элементов вместо двух.

Всего 2 ответа


Когда я пытаюсь избежать всех уродливых номеров подчеркивания, которые идут с манипуляциями с кортежем, я хотел бы использовать случайную нотацию:

rddData.map { case (a, (b, c)) => (a, b, c) }

Вы также можете присвоить своим переменным значимые имена, чтобы сделать ваш код самодокументированным, а использование фигурных скобок означает, что у вас меньше вложенных круглых скобок.

EDIT: шаблон карты {case ...} довольно компактный и может использоваться для удивительно глубоких вложенных кортежей, пока структура известна во время компиляции. Если вы абсолютно, не можете знать структуру кортежа во время компиляции, то вот какой-то взломанный, медленный код, который, вероятно, может сгладить любые произвольно вложенные кортежи ... пока не будет больше 23 элементов. Он работает, рекурсивным образом преобразуя каждый элемент кортежа в список, разбивая его на один список, а затем используя страшное отражение, чтобы преобразовать список обратно в кортеж, как показано здесь .

def flatten(b:Product): List[Any] = { 
  b.productIterator.toList.flatMap {
    case x: Product => flatten(x)
    case y: Any => List(y)
  }
}

def toTuple[Any](as:List[Any]):Product = {
  val tupleClass = Class.forName("scala.Tuple" + as.size)
  tupleClass.getConstructors.apply(0).newInstance(as.map(_.asInstanceOf[AnyRef]):_*).asInstanceOf[Product]
}

rddData.map(t => toTuple(flatten(t)))

Нет лучшего способа. 1-й ответ эквивалентен:

val abc2 = xyz.map{ case (k, v) => (k, v._1, v._2) }

что эквивалентно вашему собственному примеру.


Есть идеи?

10000