2016-03-29 7 views
0

Ich habe eine records:TypedType[(String, util.List[String])] in meiner Verbrühung Job, wo der erste Wert ist eine ID und die zweite eine Liste von Sachen. die folgenden Stellen Sie sich vor:Generiere Diff von Liste [String] in Verbrühung

("1", ["a","b","c"]) 
("1", ["a","b","c"]) 
("1", ["a","b","c"]) 
("2", ["a","b"]) 
("2", ["a","b","c"]) 
("3", ["a","b","c"]) 

Nach records.groupBy(_._1) ich nur die Datensätze ausgeben möchte, die für eine bestimmte ID voneinander unterscheiden. Für den Eingang über dem Ausgang sollte sein:

("2", ["a","b"]) 
("2", ["a","b","c"]) 

Ich bin neu in Scalding. Was ist ein eleganter Weg, dies zu erreichen?

Antwort

0

Ich weiß nicht, ob der Brüh- Aspekt Sie kritisch ist (ist Ihre Sammlung außergewöhnlich riesig?), Aber im Klar alten Scala ich tun würde:

// Given: 
val records = Seq("1" -> List("a", "b", "c"), "1" -> List("a", "b", "c"), "1" -> List("a", "b", "c"), "2" -> List("a", "b"), "2" -> List("a", "b", "c"), "3" -> List("a", "b", "c"), "3" -> List("d") 

val distinctValues = records.groupBy(_._1).map { case (k, v) => k -> v.toSet } 
// => Map(2 -> Set((2,List(a, b)), (2,List(a, b, c))), 1 -> Set((1,List(a, b, c))), 3 -> Set((3,List(a, b, c)), (3,List(d)))) 

val havingMultipleDistinct = distinctValues.map { case (k, v) => v.size > 1 } 
// => Map(2 -> Set((2,List(a, b)), (2,List(a, b, c))), 3 -> Set((3,List(a, b, c)), (3,List(d)))) 

val asRecords = havingMultipleDistinct.values.flatten 
// => List((2,List(a, b)), (2,List(a, b, c)), (3,List(a, b, c)), (3,List(d))) 
+0

yep, es muss auf einem Cluster laufen. Brühen ist grundlegend – Gevorg

0

Wenn die Größe der Werte für jeden Schlüssel ist klein genug, um in den Speicher zu passen, dann wie etwas, das sollte es tun:

records 
    .group 
    .toSet 
    .filter(_.size > 1) 
    .flatten 

Wenn es zu groß ist, dann kann man das Rohr mit sich selbst verbinden:

val grouped = records.group 
grouped 
.join(grouped) 
.collect { case(k, (a, b)) if a != b => k -> a }