2015-12-17 16 views
9

ich zu einer Gruppe von Schlüsseln einig Daten versuche, wenn der Wert eine Liste wäre:Gruppe Funken von Key (Key, List) Pair

Beispieldaten:

A 1 
A 2 
B 1 
B 2 

Erwartetes Ergebnis:

(A,(1,2)) 
(B,(1,2)) 

ich in der Lage bin dies mit dem folgenden Code zu tun:

data.groupByKey().mapValues(List(_)) 

Das Problem ist, dass, wenn ich dann versuchen, eine Map Operation wie die folgenden Funktionen ausführen:

groupedData.map((k,v) => (k,v(0))) 

Es sagt mir ich die falsche Anzahl von Parametern haben.

Wenn ich versuche:

groupedData.map(s => (s(0),s(1))) 

Es sagt mir, dass "(Any, List (Iterable (Any)) übernimmt keine Parameter"

Keine Ahnung, was ich falsch mache meine Gruppierung ist. falsch? gibt es einen besseren Weg wäre das? bitte

Scala antwortet nur zu tun. Dank !!

Antwort

12

Sie sind fast da. ersetzen Sie einfach List(_) mit _.toList

data.groupByKey.mapValues(_.toList) 
+0

Großartig! Das hat funktioniert. Mein wirkliches Problem ist, dass ich, nachdem ich das Schlüssellistenpaar hatte, versuchte, Funktionen auf der Liste mit map statt mapValues ​​auszuführen. Vielen Dank! – manjam

+0

Ich bin ein bisschen verwirrt. Ich dachte groupBy wird gegenüber reduceByKey bevorzugt. Aber heute lese ich [einige Artikel] (https: //databricks.gitbooks.io/databricks-spark-wissensbasis/content/best_practices/prefer_reducebykey_over_groupbykey.html), die das Gegenteil anzeigen. Also welches ist wahr? – Matthias

+0

@Matthias Dafür gibt es keine gute Antwort ohne Kontext. Abhängig von einer Sprache, API und Operation kann eine dieser Optionen eine gültige Wahl sein. – zero323

3

Wenn Sie eine anonyme Inline-Funktion der Form schreiben

ARGS => OPERATION 

der gesamte Teil vor dem Pfeil (=>) als Argumentliste genommen. Im Fall von

(k, v) => ... 

interpretiert der Interpreter das als eine Funktion, die zwei Argumente benötigt. In Ihrem Fall haben Sie jedoch ein einzelnes Argument, bei dem es sich um ein Tupel handelt (hier eine Tuple2 oder eine Pair - genauer, Sie scheinen eine Liste von Pair[Any,List[Any]] zu haben). Es gibt ein paar Möglichkeiten, um dies zu umgehen. Erstens können Sie die gebrannte Form verwenden, um ein Paar darstellen, in einem zusätzlichen Satz von Klammern eingewickelt zu zeigen, dass dies das einzige erwartete Argument für die Funktion:

((x, y)) => ... 

oder können Sie die anonyme Funktion in dem Schreib Form einer Teilfunktion, die auf Tupel entspricht:

groupedData.map(case (k,v) => (k,v(0))) 

Schließlich können Sie einfach mit einem einzigen angegebenen Argumente, wie pro Ihrem letzten Versuch gehen, aber - es zu merken ist ein Tupel - verweist auf den spezifischen Bereich (e) innerhalb des Tupels, das Sie benötigen:

groupedData.map(s => (s._2(0),s._2(1))) // The key is s._1, and the value list is s._2