如何在scala中反转地图?

时间:2013-04-07 11:08:40

标签: scala scala-collections

Scala中从Map[K, V]转换为Map[V, Iterable[K]]的最短/惯用方式是什么?

2 个答案:

答案 0 :(得分:7)

Marius的解决方案可以使用mapValues简化,

m.groupBy(_._2).mapValues(_.map(_._1))

示例REPL会话,

scala> val m = Map(1 -> "foo", 2 -> "foo", 3 -> "bar", 4 -> "bar", 5 -> "baz")
m: Map[Int,String] = Map(5 -> baz, 1 -> foo, 2 -> foo, 3 -> bar, 4 -> bar)

scala> m.groupBy(_._2).mapValues(_.map(_._1))
res0: Map[String, Iterable[Int]] = Map(baz -> List(5), foo -> List(1, 2), bar -> List(3, 4))

答案 1 :(得分:3)

这应该可以解决问题:

def invert[A, B](m: Map[A, B]): Map[B, Iterable[A]] = {
  m.groupBy(_._2).map {
    case (v, kvPairs) => (v, kvPairs.map(_._1))
  }
}

这会迭代映射中的键值对,并使用值对这些对进行分组(_._2是元组的第二个元素的getter。)

这会得到一个对列表,其中第一个元素是值,第二个元素是一个序列,其中包含原始映射中具有值的第二个元素的所有对。

最后,对于后面这些对中的每一对,我们只从序列中提取第一个元素 - 从而获得在原始地图中映射到它的所有键的值。