Scala:将Map映射到元组列表

时间:2015-02-27 16:06:46

标签: list scala dictionary tuples seq

我尝试使用Map.map将地图转换为元组列表。 然而,这失败了。我做了以下实验:

val m = Map(("a" -> 1), ("b" -> 2))
         //> m  :     scala.collection.immutable.Map[String,Int] = Map(a -> 1, b -> 2)
val r1 = m.map{ case (k,v) => v}                //> r1  : scala.collection.immutable.Iterable[Int] = List(1, 2)
def toTuple[A,B](a:A,b:B) = (a,b)               //> toTuple: [A, B](a: A, b: B)(A, B)
//val r2: List[Tuple2[_,_]] = m.map(e => (e._1,e._2))
val r3 = m.map(e => toTuple(e._1,e._2))         //> r3  : scala.collection.immutable.Map[String,Int] = Map(a -> 1, b -> 2)
val r4 = m.toSeq                                //> r4  : Seq[(String, Int)] = ArrayBuffer((a,1), (b,2))

注意如何为单个元素(r1)生成List,但为元组(r3)生成Map。甚至不强迫类型工作(r2)。只有对Seq的显式调用才能做到(r4)所以我的问题是,为什么/如何“自动”创建一个新的Map而不是列表呢?实际上如何确定返回类型(Seq,List等)

1 个答案:

答案 0 :(得分:19)

Map已经是元组的集合。

scala> "b" -> 2
res0: (String, Int) = (b,2) // Implicitly converted to a Tuple

当您映射Map时,您需要映射其包含的(键,值)对。这不起作用,因为您正在剥离密钥,并仅保留值。所以你拥有的不再是Map,而是集合层次结构的一两步,Iterable

val r1 = m.map{ case (k,v) => v} 

强制该类型无效,因为Map[A, B]不是List[(A, B)]。这相当于m.map(identity)。请注意您甚至是如何使用元组访问器访问e

val r2: List[Tuple2[_,_]] = m.map(e => (e._1,e._2))

val r3 = m.map(e => toTuple(e._1,e._2))

此处,SeqList更广义:

val r4 = m.toSeq

@EndeNeu所述的简单解决方案就是使用toList。当你map一个集合时,如果可以,它应该返回原始集合类型。因此,映射Map应该返回另一个Map,除非底层结构使其不再是Map中的r1(例如完全删除密钥)。