list Scala:将 Map 映射到元组列表

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28769367/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 08:06:51  来源:igfitidea点击:

Scala: map a Map to list of tuples

listscaladictionarytuplesseq

提问by user2051561

I tried to use Map.map to convert a map into a List of Tuples. However this fails. I did the following experiments:

我尝试使用 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))

Notice how a List is generated for single elements (r1) but a Map is produced for tuples (r3). Not even forcing the type worked (r2). Only an explicit call to Seq did it (r4) So my question is, why/how does Map.map "automagically" create a new Map and not a list for example? In fact how is the return type determined (Seq, List, etc.)

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

回答by Michael Zajac

A Mapis a collection of tuples already.

AMap已经是元组的集合。

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

When you're mapping a Map, you're mapping the (key, value) pairs that it contains. This can't work, because you're stripping away the keys, and retaining only the values. So what you have is no longer a Map, but a step or two up the collection hierarchy, an Iterable:

映射 a 时Map,就是映射它包含的 (key, value) 对。这是行不通的,因为您正在剥离键,只保留值。所以你所拥有的不再是一个Map,而是集合层次结构的一两步,一个Iterable

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

Forcing the type cannot work, because a Map[A, B]is not a List[(A, B)]. This is the equivalent of m.map(identity). Notice how you're even accessing ewith tuple accessors:

强制类型不起作用,因为 aMap[A, B]不是 a 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))

Here, Seqis more generalized than List:

在这里,Seq比 更普遍List

val r4 = m.toSeq

The simple solution as stated by @EndeNeu is to just use toList. When you mapa collection, it should return the original collection type if it can. So mapping a Mapshould return another Map, unless the underlying structure has made it no longer a Map(like removing keys entirely) in r1.

@EndeNeu 所述的简单解决方案是使用toList. 当您创建map一个集合时,如果可以,它应该返回原始集合类型。所以映射 aMap应该返回 another Map,除非底层结构使它不再是 a Map(就像完全删除键) in r1