如何将元组元组转换为地图

时间:2013-04-22 05:41:33

标签: scala

我有Tuple Tuple个,需要将其转换为Map。例如

(("a", 3), ("b", 1), ("c", 7), ..., ("z", 10))

应该会产生Map

Map("a" -> 3, "b" -> 1, ..., "z" -> 10)

在Scala中执行此操作的方法有哪些?

4 个答案:

答案 0 :(得分:6)

scala> tuples
res0: ((String, Int), (String, Int), (String, Int)) = ((a,3),(b,1),(c,7))


scala> tuples.productIterator.map{case (a,b)=> (a -> b)}.toMap
res1: scala.collection.immutable.Map[Any,Any] = Map(a -> 3, b -> 1, c -> 7)


scala> res1("a")
res2: Any = 3

scala> res1("b")
res3: Any = 1

scala> res1("c")
res4: Any = 7

答案 1 :(得分:2)

如果你愿意将依赖项纳入你的项目中,那么这类类型的东西就是shapeless有用的东西:

> shapeless-core/console
[warn] Credentials file /home/folone/.ivy2/.credentials does not exist
[info] Compiling 24 Scala sources to /home/folone/workspace/shapeless/core/target/scala-2.11/classes...
[info] Starting scala interpreter...
[info] 
Welcome to Scala version 2.11.0-20130205-141957-132e09fc2e (OpenJDK 64-Bit Server VM, Java 1.7.0_17).
Type in expressions to have them evaluated.
Type :help for more information.

scala> import shapeless._
import shapeless._

scala> import Tuples._
import Tuples._

scala> val tuples = (("a", 3), ("b", 1), ("c", 7), ("z", 10))
tuples: ((String, Int), (String, Int), (String, Int), (String, Int)) = ((a,3),(b,1),(c,7),(z,10))

scala> tuples.hlisted.toList.toMap
res2: scala.collection.immutable.Map[String,Int] = Map(a -> 3, b -> 1, c -> 7, z -> 10)

与其他解决方案相比,在编译时检查所有类型。所以,这不会编译:

scala> val tuples = (("a", 3), ("b", 1), ("c", 7), ("z", "hello"))
tuples: ((String, Int), (String, Int), (String, Int), (String, String)) = ((a,3),(b,1),(c,7),(z,hello))

scala> tuples.hlisted.toList.toMap
<console>:15: error: could not find implicit value for parameter toList: shapeless.ToList[shapeless.::[(String, Int),shapeless.::[(String, Int),shapeless.::[(String, Int),shapeless.::[(String, String),shapeless.HNil]]]],Lub]
              tuples.hlisted.toList.toMap
                             ^

这是2012年nescala上的@milessabin's talk,包括HList的一些信息。如果你愿意,here's今年最新的无形热度。

答案 2 :(得分:1)

作为第一步,对于任意元组t(实际上是scala.Product的实例),您可以使用t.productIterator获取Iterator[Any]的组件。

然后,要获得地图,您可以执行以下操作:

t.productIterator.asInstanceOf[Iterator[(String, Int)]].toMap

备注:在你的情况下使用元组似乎有点奇怪,因为参数的类型是同构的。为什么不使用List[(String, Int)]之类的

List(("a", 3), ("b", 1), ("c", 7), ..., ("z", 10))

答案 3 :(得分:1)

两个最简洁的解决方案:

scala> tuples
res50: ((String, Int), (String, Int), (String, Int)) = ((a,3),(b,1),(c,7))

scala> tuples.productIterator.map{case t: (String, Int) => t}.toMap
res51: scala.collection.immutable.Map[String,Int] = Map(a -> 3, b -> 1, c -> 7)

scala> tuples.productIterator.map(_.asInstanceOf[(String, Int)]).toMap
res54: scala.collection.immutable.Map[String,Int] = Map(a -> 3, b -> 1, c -> 7)