4

我有一个 Map[String,Seq[String]] 并且想基本上将其转换为 Map[String,String] 因为我知道该序列只有一个值。

4

4 回答 4

4

其他人已经提到过mapValues,但如果我是你,我会这样做:

scala> val m = Map(1 -> Seq(1), 2 -> Seq(2))
m: scala.collection.immutable.Map[Int,Seq[Int]] = Map(1 -> List(1), 2 -> List(2))

scala> m.map { case (k,Seq(v)) => (k,v) }
res0: scala.collection.immutable.Map[Int,Int] = Map(1 -> 1, 2 -> 2)

两个原因:

  1. mapValues方法生成结果 Map 的视图,这意味着每次访问元素时都会重新计算该函数。除非您计划只访问每个元素一次,或者您只计划访问其中的一小部分,否则您不希望重新计算发生。

  2. 使用 case with(k,Seq(v))可确保在函数看到不包含一个元素的Seq时抛出异常。如果有零个元素,使用_(0)or_.head会抛出异常,但如果你有多个元素,则不会抱怨,这可能会导致稍后在没有错误的情况下丢失东西时出现神秘的错误。

于 2012-09-18T17:53:23.863 回答
3

您可以使用mapValues().

scala> Map("a" -> Seq("aaa"), "b" -> Seq("bbb"))
res0: scala.collection.immutable.Map[java.lang.String,Seq[java.lang.String]] = M
ap(a -> List(aaa), b -> List(bbb))

scala> res0.mapValues(_(0))
res1: scala.collection.immutable.Map[java.lang.String,java.lang.String] = Map(a
-> aaa, b -> bbb)
于 2012-09-18T17:36:51.910 回答
0

我想我通过执行以下操作得到了它:

mymap.flatMap(x => Map(x._1 -> x._2.head))
于 2012-09-18T17:36:11.127 回答
0

还有一个建议:

m mapValues { _.mkString }

这与 Seq 是否有多个元素无关——它只会将所有字符串连接在一起。如果您担心每个值的重新计算,您可以提前进行:

(m mapValues { _.mkString }).view.force
于 2012-09-18T23:07:07.207 回答