Scala:将 Map 映射到元组列表
Scala: map a Map to list of tuples
我尝试使用 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) 所以我的问题是,why/how Map.map "automagically" 是否创建了一个新的 Map 而不是一个列表?实际上return类型是如何确定的(Seq、List等)
一个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))
这里,Seq
比List
更通用:
val r4 = m.toSeq
@EndeNeu 所述的简单解决方案是只使用 toList
。当你 map
一个集合时,如果可以的话,它应该 return 原始集合类型。所以映射一个 Map
应该 return 另一个 Map
,除非底层结构使它不再是 r1
中的 Map
(比如完全删除键)。
为什么还要麻烦一张地图?将数据结构设为 List[(String,Int)]
是否更适合您的用例?基本一样..你甚至可以用地图符号来写:
val myMapAsList: List[(String, Int)] = List[(String,Int)](
"a" -> 1,
"b" -> 2
) // yields val myMapAsList: List[(String, Int)] = List((a,1), (b,2))
我尝试使用 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) 所以我的问题是,why/how Map.map "automagically" 是否创建了一个新的 Map 而不是一个列表?实际上return类型是如何确定的(Seq、List等)
一个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))
这里,Seq
比List
更通用:
val r4 = m.toSeq
@EndeNeu 所述的简单解决方案是只使用 toList
。当你 map
一个集合时,如果可以的话,它应该 return 原始集合类型。所以映射一个 Map
应该 return 另一个 Map
,除非底层结构使它不再是 r1
中的 Map
(比如完全删除键)。
为什么还要麻烦一张地图?将数据结构设为 List[(String,Int)]
是否更适合您的用例?基本一样..你甚至可以用地图符号来写:
val myMapAsList: List[(String, Int)] = List[(String,Int)](
"a" -> 1,
"b" -> 2
) // yields val myMapAsList: List[(String, Int)] = List((a,1), (b,2))