2017-01-12 28 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 } } 

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