Scala中从Map[K, V]
转换为Map[V, Iterable[K]]
的最短/惯用方式是什么?
答案 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。)
这会得到一个对列表,其中第一个元素是值,第二个元素是一个序列,其中包含原始映射中具有值的第二个元素的所有对。
最后,对于后面这些对中的每一对,我们只从序列中提取第一个元素 - 从而获得在原始地图中映射到它的所有键的值。