我有一个Tuple
of Tuple
s,需要将其转换为一个Map
. 例如
(("a", 3), ("b", 1), ("c", 7), ..., ("z", 10))
应该导致Map
Map("a" -> 3, "b" -> 1, ..., "z" -> 10)
在 Scala 中有哪些方法可以做到这一点?
我有一个Tuple
of Tuple
s,需要将其转换为一个Map
. 例如
(("a", 3), ("b", 1), ("c", 7), ..., ("z", 10))
应该导致Map
Map("a" -> 3, "b" -> 1, ..., "z" -> 10)
在 Scala 中有哪些方法可以做到这一点?
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
如果您愿意将依赖项引入您的项目,那么这种类型级别的东西就是 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
^
这是@milessabin在 nescala 2012 上的演讲,包括一些关于HList
s 的信息。如果你喜欢,这里是今年最新的无形热度。
作为第一步,对于任意元组t
(实际上是 的实例scala.Product
),您可以使用它t.productIterator
来获取Iterator[Any]
其组件。
然后,要获取地图,您可以执行以下操作:
t.productIterator.asInstanceOf[Iterator[(String, Int)]].toMap
备注:在您的情况下使用元组似乎有点奇怪,因为参数的类型是同质的。为什么不使用List[(String, Int)]
like
List(("a", 3), ("b", 1), ("c", 7), ..., ("z", 10))
两个最简洁的解决方案:
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)