如何将Map[String,Seq[String]]转换为Map[String,String]

4

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


这个操作被称为“map”(不要与Map ADT混淆)。已经尝试了什么? - user166390
看起来有人在一月份问了一个非常类似的问题:https://dev59.com/f1_Va4cB1Zd3GeqPTGzE - dhg
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. 使用带有 (k,Seq(v)) 的 case 语句可以确保如果该函数看到一个不包含 恰好 一个元素的 Seq,则会抛出异常。使用 _(0)_.head 将在没有元素时抛出异常,但如果有多个元素,则不会发出警告,这可能会导致后来出现神秘错误时缺少东西而没有错误。


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)

1
.head而不是(0)是惯用语。 - om-nom-nom

0

另一个建议:

m mapValues { _.mkString }

这段代码与 Seq 中是否有多个元素无关,它只是将所有字符串连接在一起。如果你担心每个值的重新计算,可以事先让它发生:

(m mapValues { _.mkString }).view.force

0

我认为我通过以下方式理解了它:

mymap.flatMap(x => Map(x._1 -> x._2.head))

这只是一个开始。考虑将其放入帖子中。然而,使用普通的 map(或其他专门的函数)可以更简单、更有效地完成。 - user166390

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接