Scala:将 Map 映射到元组列表

Posted

技术标签:

【中文标题】Scala:将 Map 映射到元组列表【英文标题】:Scala: map a Map to list of tuples 【发布时间】:2015-04-30 10:03:00 【问题描述】:

我尝试使用 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.map “自动”创建一个新 Map 而不是一个列表?其实返回类型是如何确定的(Seq、List等)

【问题讨论】:

m.toList 有什么问题?另请注意,集合上的映射会返回相同类型的另一个集合,因此您不能真正返回 Map 上的列表映射,除非您在其上调用 .toList @Ende - 没有错。请参阅下面的评论。 【参考方案1】:

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,除非底层结构使它不再是r1 中的Map(就像完全删除键)。

【讨论】:

谢谢 m-z。我的问题是:在r1 的情况下,Map 怎么知道它应该转换为List?可能是别的东西?为什么不是数组?我假设他们是在这里进行的一些隐式转换。因此我通过强制类型进行测试。关于元组,是有道理的。这就是地图约定。 @user2051561 它不会在r1 中将其转换为List——它会返回Iterable,因为这是与您拥有的集合类型匹配的层次结构中下一个最接近的特征。 Map 扩展 Iterable.

以上是关于Scala:将 Map 映射到元组列表的主要内容,如果未能解决你的问题,请参考以下文章

scala zip列表到元组

Scala的映射和元组操作

Scala学习 —— 元组&映射

第1节 Scala基础语法:11映射;12元组

「大数据」(八十九)Scala之映射和元组

Scala从入门到精通之四-映射和元组