3

在 Scala 中从Map[K, V]to反转的最短/惯用方法是什么?Map[V, Iterable[K]]

4

2 回答 2

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))
于 2013-04-07T12:53:13.510 回答
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)。

这为我们提供了一个对列表,其中第一个元素是值,第二个元素是一个序列,其中包含原始映射中第二个元素具有该值的所有对。

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

于 2013-04-07T11:19:56.010 回答