什么是最简洁的Scala方法来反转地图?
什么是最简洁的Scala方法来反转地图映射可能包含非唯一值。 编辑:什么是最简洁的Scala方法来反转地图?,scala,scala-2.8,scala-collections,Scala,Scala 2.8,Scala Collections,什么是最简洁的Scala方法来反转地图映射可能包含非唯一值。 编辑: Map[A,B]的反转应该会得到Map[B,Set[A]](或者是一个多重映射,那会更好)。如果您可能丢失重复的密钥: scala> val map = Map(1->"one", 2->"two", -2->"two") map: scala.collection.immutable.Map[Int,java.lang.String] = Map((1,one), (2,two), (-2,two))
Map[A,B]
的反转应该会得到Map[B,Set[A]]
(或者是一个多重映射,那会更好)。如果您可能丢失重复的密钥:
scala> val map = Map(1->"one", 2->"two", -2->"two")
map: scala.collection.immutable.Map[Int,java.lang.String] = Map((1,one), (2,two), (-2,two))
scala> map.map(_ swap)
res0: scala.collection.immutable.Map[java.lang.String,Int] = Map((one,1), (two,-2))
如果不希望以多重映射的形式访问,只需映射到集合,然后:
scala> map.groupBy(_._2).mapValues(_.keys.toSet)
res1: scala.collection.immutable.Map[
java.lang.String,scala.collection.immutable.Set[Int]
] = Map((one,Set(1)), (two,Set(2, -2)))
如果您坚持要获得一个多重映射
,那么:
scala> import scala.collection.mutable.{HashMap, Set, MultiMap}
scala> ( (new HashMap[String,Set[Int]] with MultiMap[String,Int]) ++=
| map.groupBy(_._2).mapValues(Set[Int]() ++= _.keys) )
res2: scala.collection.mutable.HashMap[String,scala.collection.mutable.Set[Int]]
with scala.collection.mutable.MultiMap[String,Int] = Map((one,Set(1)), (two,Set(-2, 2)))
编辑以澄清问题:
object RevMap {
def
main(args: Array[String]): Unit = {
val m1 = Map("one" -> 3, "two" -> 3, "three" -> 5, "four" -> 4, "five" -> 5, "six" -> 3)
val rm1 = (Map[Int, Set[String]]() /: m1) { (map: Map[Int, Set[String]], pair: (String, Int)) =>
map + ((pair._2, map.getOrElse(pair._2, Set[String]()) + pair._1)) }
printf("m1=%s%nrm1=%s%n", m1, rm1)
}
}
% scala RevMap
m1=Map(four -> 4, three -> 5, two -> 3, six -> 3, five -> 4, one -> 3)
rm1=Map(4 -> Set(four, five), 5 -> Set(three), 3 -> Set(two, six, one))
我不确定这算不上简洁。那么:
implicit class RichMap[A, B](map: Map[A, Seq[B]])
{
import scala.collection.mutable._
def reverse: MultiMap[B, A] =
{
val result = new HashMap[B, Set[A]] with MultiMap[B, A]
map.foreach(kv => kv._2.foreach(result.addBinding(_, kv._1)))
result
}
}
或
定义如果给定值在多个键下出现时会发生什么情况。但是更好的开始会更清晰,例如Map(1->“一”,2->“二”,3->“二”,4->“二”)
implicit class RichMap[A, B](map: Map[A, Seq[B]])
{
import scala.collection.mutable._
def reverse: MultiMap[B, A] =
{
val result = new HashMap[B, Set[A]] with MultiMap[B, A]
map.foreach(kv => kv._2.foreach(result.addBinding(_, kv._1)))
result
}
}
implicit class RichMap[A, B](map: Map[A, Seq[B]])
{
import scala.collection.mutable._
def reverse: MultiMap[B, A] =
{
val result = new HashMap[B, Set[A]] with MultiMap[B, A]
map.foreach{case(k,v) => v.foreach(result.addBinding(_, k))}
result
}
}