0
votes

I have a map in Scala in which each key maps to a value which is a list of an indeterminate lists. AKA the map's type is [String,List[List[String]]]. I need to add together the third value (value3) of each list, in each map key. However, I don't know how to do that because each key has a different number of lists in it's corresponding value. Example:

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

How would I go about doing this?

1
What exactly do you mean by "add together"? The values are Strings? So append them? Or get a List of them? Or something else? - dth

1 Answers

1
votes

You need a default value in case one of the lists has fewer than 3 elements.

Also, you need to define what you mean by "add" since you have strings. you could get a list or concatenate them in a string.

You want to do this by key so you map the values. You then drop 2 items for each list to get the optional third (None if the list has fewer than 3 items, Some(x) otherwise). Since we flatMap, we get a list of all the "third items" and we can concatenate them or anything else.

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"

Here is a slightly more generic version in which you can fold over the nth items of a map of list of lists. It's not the most generic you could get, but you get the idea

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