2

我有一个Tupleof Tuples,需要将其转换为一个Map. 例如

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

应该导致Map

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

在 Scala 中有哪些方法可以做到这一点?

4

4 回答 4

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
于 2013-04-22T05:58:24.887 回答
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
                             ^

这是@milessabin在 nescala 2012 上的演讲,包括一些关于HLists 的信息。如果你喜欢,这里是今年最新的无形热度。

于 2013-04-22T08:57:59.737 回答
1

作为第一步,对于任意元组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))
于 2013-04-22T05:53:42.837 回答
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)
于 2013-09-08T10:18:15.067 回答