2017-01-12 27 views
0

我有一張地圖定義如下。該鍵代表一個用戶ID和值表示和AddressId。扭轉地圖,但使用值作爲鍵,並使用鍵作爲值

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

我想知道反向映射,這意味着每個列表中我要使它成爲一個關鍵的每一個項目,和值是鍵的列表。

所以基本上對於每個AddressID我都會有一個UserID列表。

我該怎麼做?

我知道我可以使用mapValues,但我需要以某種方式引用回密鑰。

這樣做不會創建列表:

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

的思考?

回答

2

定期斯卡拉

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

如果您使用Scalaz

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

如果我有一個地圖[長,將[龍]將這種變化的東西呢? –

+0

@coolbreeze普通的Scala解決方案仍然可以工作 - 在'Vector'上的'flatMap'之後,你仍然得到一個'Vector [(Long,Long)]',但結果將是'Map [Int,List [Int]' ,所以你需要'mapValues'中的'.toSet'。 Scalaz/cats,IIRC,不允許對'Set'使用foldMap,至少沒有額外的依賴關係 –

0

這是一個潛在的解決方案:

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 } } 

不是最優雅的方法,但它似乎在我身邊工作。