我有Tuple
Tuple
个,需要将其转换为Map
。例如
(("a", 3), ("b", 1), ("c", 7), ..., ("z", 10))
应该会产生Map
Map("a" -> 3, "b" -> 1, ..., "z" -> 10)
在Scala中执行此操作的方法有哪些?
答案 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)