我的逆Scala的地图: X:[B,C] Y:并[b,d,E] Z:[d,F,G,H]如何计算多图
我想要查找此映射的逆。 b:[x,y] c:[x] d:[x,z]等等。
有没有办法做到这一点,而不使用在中间可变地图
如果它不是一个多地图 - 然后以下工作:
typeMap.flatMap { case (k, v) => v.map(vv => (vv, k))}
我的逆Scala的地图: X:[B,C] Y:并[b,d,E] Z:[d,F,G,H]如何计算多图
我想要查找此映射的逆。 b:[x,y] c:[x] d:[x,z]等等。
有没有办法做到这一点,而不使用在中间可变地图
如果它不是一个多地图 - 然后以下工作:
typeMap.flatMap { case (k, v) => v.map(vv => (vv, k))}
编辑:固定的答案,包括什么马斯理所当然指出。我的回答比他更努力,因为我试图通过每一步,而不是使用flatMaps提供的教育用于教育目的,他更直截了当:)
我不确定你的符号。我假设你有什么是一样的东西:
val myMap = Map[T, Set[T]] (
x -> Set(b, c),
y -> Set(b, d, e),
z -> Set(d, f, g, h)
)
可以实现反向查找如下:
val instances = for {
keyValue <- myMap.toList
value <- keyValue._2
}
yield (value, keyValue._1)
在这一点上,您的实例变量的类型的列表:
(b, x), (c, x), (b, y) ...
如果你现在要做的:
val groupedLookups = instances.groupBy(_._1)
你得到:
b -> ((b, x), (b, y)),
c -> ((c, x)),
d -> ((d, y), (d, z)) ...
现在我们要减少数值,以便使它们只包含每一对的第二部分。因此,我们这样做:
val reverseLookup = groupedLookup.map(_._1 -> _._2.map(_._2))
这意味着对于每对我们保持原有的关键,但我们的参数列表映射到的东西,只有一对的第二个值。
在那里你有你的结果。
(您也可避免被指派给中间结果,但我认为它是这样的更清晰)
您构建'instances'的方式转换为'.flatMap'。 '结果集合的类型由静态类型的不可变映射引导。“(请参见[#flatMap](http://www.scala-lang.org/api/2.10.4/index.html#scala.collection .immutable.Map)),这意味着'instances'是一个'Map [A,B]',并且在这个过程中你将失去一些元组。 – Marth 2014-10-28 18:49:09
你说得对。我修正了它,以便在更加详细的过程中反映出正确的方式,但我也提高了您的答案,因为它更直接 – 2014-10-28 20:38:01
另外 - groupedLookup.map(_._ 1 - > _._ 2.map(_。_2))只能是 - groupedLookup.mapValues(_。flatMap(_._ 2)) – 2015-03-24 20:13:33
这里是我的简化的功能:
def reverseMultimap[T1, T2](map: Map[T1, Seq[T2]]): Map[T2, Seq[T1]] =
map.toSeq
.flatMap { case (k, vs) => vs.map((_, k)) }
.groupBy(_._1)
.mapValues(_.map(_._2))
以上是从@Diego Martinoia衍生“在下面的函数格式中对其进行了修正和转载:
def reverseMultimap[T1, T2](myMap: Map[T1, Seq[T2]]): Map[T2, Seq[T1]] = {
val instances = for {
keyValue <- myMap.toList
value <- keyValue._2
} yield (value, keyValue._1)
val groupedLookups = instances.groupBy(_._1)
val reverseLookup = groupedLookups.map(kv => kv._1 -> kv._2.map(_._2))
reverseLookup
}
您能否将此标记为已完成并选择答案? – 2015-03-25 09:59:54