在Scala中具有多个列表的地图中添加值

时间:2016-02-07 22:44:44

标签: list scala dictionary

我在Scala中有一个映射,其中每个键都映射到一个值,该值是一个不确定列表的列表。 AKA地图的类型是[String,List[List[String]]]。我需要在每个映射键中将每个列表的第三个值(value3)加在一起。但是,我不知道该怎么做,因为每个密钥都有不同数量的列表,其中包含相应的值。例如:

Map(String -> List(List(value1, value2, value3, value4), List(value1, value2, value3, value4), List(value1, value2, value3, value4)))

我将如何做到这一点?

1 个答案:

答案 0 :(得分:1)

如果其中一个列表少于3个元素,则需要一个默认值。

此外,你需要定义你的意思"添加"因为你有字符串。你可以得到一个列表或将它们连接成一个字符串。

您希望通过键执行此操作,以便映射值。然后为每个列表删除2个项目以获得可选的第三个项目(如果列表少于3个项目则为None,否则为Some(x))。从我们flatMap,我们得到所有"第三项"我们可以连接它们或其他任何东西。

val map = Map("a" -> List(List("a", "b", "c", "d"), List("a", "b"), List("x", "y", "z")))

map.mapValues(_.flatMap(_.drop(2).headOption)) // returns "a" -> List("c", "z")
map.mapValues(_.flatMap(_.drop(2).headOption).mkString) // returns "a" -> "cz"

这是一个稍微更通用的版本,您可以在其中折叠列表列表的第n个项目。它不是你能得到的最通用的,但你明白了

def foldNth[A, R](xs: Traversable[Traversable[A]], n: Int, z: R)(add: (R, A) => R) =
  xs.flatMap(_.drop(n).headOption).foldLeft(z)(add)

map.mapValues(foldNth(_, 2, Vector[String]())(_ :+ _)) // concatenates them in a vector
map.mapValues(foldNth(_, 2, "")(_ + _)) // concatenates them in a string