2017-01-12 5 views
0

Ich habe eine Karte unten definiert. Der Schlüssel repräsentiert eine UserID und der Wert repräsentiert und AddressId.Umkehren einer Karte, aber mit den Werten als Schlüssel und Schlüssel als Werte

val m: Map[Int, List[Int]] 

Ich möchte wissen, die Karte umgekehrt, denn in jeder Liste jedes Element bedeutet, ich möchte es einen Schlüssel machen, und der Wert eine Liste der Schlüssel sein.

Also im Grunde für jede AddressID werde ich eine Liste von UserIDs haben.

Wie kann ich das tun?

Ich weiß, ich kann MapValues ​​verwenden, aber ich muss irgendwie zurück auf den Schlüssel verweisen.

Dadurch wird die Liste nicht erstellt werden:

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

Gedanken?

Antwort

2

Regular Scala

m 
    .toVector 
    .flatMap { case (k, vs) => vs.map(_ -> k) } 
    .groupBy { case (v, _) => v } 
    .mapValues { _.map { case (_, k) => k } } 

Wenn Sie mit Katzen oder Scalaz:

m.toVector foldMap { case (k, vs) => vs foldMap (v => Map(v -> List(k))) } 
+0

Wenn ich eine Karte [Lang, Set [Long]] würde das ändern Dinge haben? –

+0

@coolbreeze die normale Scala-Lösung würde immer noch funktionieren - nach 'flatMap' auf einem' Vector' erhalten Sie immer noch einen 'Vector [(Long, Long)]', aber das Ergebnis wäre 'Map [Int, List [Int]' Sie benötigen also ein '.toSet' in' mapValues'. Scalaz/cats, IIRC, erlauben foldMap on 'Set' nicht, zumindest ohne zusätzliche Abhängigkeiten –

0

Hier ist eine mögliche Lösung:

val m = Map(1 -> List("a","b"), 2 -> List("c","a")) 

val m1 = m.toList.flatMap{ case(key,valueList) => valueList.map(value => (value,key))}.groupBy{ _._1 } 

m1.map{ case(key,valueList) => key -> valueList.map{case (x,y) => y } } 

Nicht die eleganteste Methode, aber es scheint auf meiner Seite zu arbeiten.

Verwandte Themen