2017-01-12 4 views
1

Der Versuch, eine Map[Long, Set[Long]] in eine Map[Long, Long] umzuwandeln.Invertieren einer Karte [Long, Set [Long]) zu einer Karte [Long, Long]

habe ich versucht, diese aber haben Probleme kompilieren:

m.map(_.swap).map(k => k._1.map((_, k._2))) 

Beispiel:

Map(10 -> Set(1,2,3), 11 -> Set(4,5)) 

werden sollte:

Map(1 -> 10, 
    2 -> 10, 
    3 -> 10, 
    4 -> 11, 
    5 -> 11) 
+1

Was möchten Sie erreichen? Was sollten die Schlüssel und Werte in der Ergebniskarte sein? – slouc

+0

Jeder Wert sollte ein Schlüssel sein, und der Wert dieses Schlüssels ist der Schlüssel. Ich werde meine Q –

Antwort

1

in Unter der Annahme, ist Ihr Map[Long, Set[Long]]:

in./:(Map.empty[Long, Long]) { case (acc, (key, values)) => acC++ values.map(_ -> key) } 
1

Um zu klären, scheinen, wie Sie dieses haben:

Map(10 -> Set(1,2,3), 11 -> Set(4,5)) 

Und wollen Sie diese Karte in einer anderen Karte konvertieren, aber mit so etwas wie:

Map(1 -> 10, 
    2 -> 10, 
    3 -> 10, 
    4 -> 11, 
    5 -> 11) 

Wie Sie, wenn die Sätze nicht disjunkt zu sehen sind, fehlen einige Schlüssel in der Folge Karte mit werden:

dies in Betracht zu haben, wird der Code wie folgt aussehen:

val m: Map[Long, Set[Long]] = Map(10l -> Set(1l,2l,3l), 11l -> Set(4l,5l)) 

m.map(_.swap).map(k => k._1.map((_, k._2))) 

val foo: Iterable[(Long, Long)] = m.flatMap { t => 
    val (key, value) = t 
    value.map(_ -> key) 
} 

val result: Map[Long, Long] = foo.toMap 
+0

aktualisieren, wie wird ein Schlüssel fehlen? –

+0

Probieren Sie das gleiche Beispiel mit dieser Karte: Karte (10l -> Set (1l, 2l, 3l, 4l), 11l -> Set (4l, 5l)) ist, weil auf einer Karte nicht wiederholt Schlüssel haben können .. – damdev

+0

die Werte sind garantiert einzigartig. Es wird also keinen Wert geben, der auf denselben Schlüssel verweist. –

1

Dies wird Ihre MapmMap[Long, Set[Long]]-Map[Long, List[Long]] invertieren.

m flatten {case(k, vs) => vs.map((_, k))} groupBy (_._1) mapValues {_.map(_._2)} 

Sie haben nicht angegeben, was passieren soll, wenn verschiedene Set Werte zum Teil die gleichen Long s enthält (das heißt Map(8 -> Set(1,2), 9 -> Set(2,3))). Wenn Sie sicher sind, dass dies nicht passieren wird, können Sie die folgende Einstellung verwenden.

m flatten {case(k, vs) => vs.map((_, k))} groupBy (_._1) mapValues {_.head._2} 

Oder noch einfacher:

m.flatten {case(k, vs) => vs.map((_, k))}.toMap 
+0

es wird nicht passieren, die Werte sind alle einzigartig und werden nicht immer auf den gleichen Schlüssel zeigen. Das Ergebnis muss eine Map [Long, Long] sein, keine Map [Long, List [Long]] –

3

flatMap auf Map[A,B] wird "einfach funktionieren" mit Sammlungen von Tupeln:

m.flatMap {case (k,v) => v.map(_ -> k)} // Map[Long,Long] 

geht von einem Map[Long,Set[Long]] zu einer Reihe von Set[(Long,Long)], die zu einem Map[Long,Long] abgeflacht wird.

Verwandte Themen