kevinz315
kevinz315

Reputation: 9

Scala folding tuples

Map(Mary -> List(("Mary", 7065), ("Mary", 2604), ("Mary", 1414))):
  Map[String, List[(String, Int)]]

How can I fold the maps to produce something like

Map("Mary" -> List(("Mary", 7065+2604+1414))):
  Map[String, List[(String, Int)]]

?

Upvotes: 1

Views: 497

Answers (3)

zenofsahil
zenofsahil

Reputation: 1753

val data = Map("Mary" -> List(("Mary", 7065), ("Mary", 2604), ("Mary", 1414)))

data map { case (x,y) => (x, y.foldLeft(0)((acc, elem) => acc + elem._2)) }

This results in the Map: scala.collection.immutable.Map[String,Int] = Map(Mary -> 11083)

Upvotes: 0

Nagarjuna Pamu
Nagarjuna Pamu

Reputation: 14825

For your special case you can use this

map.map { case (k, v) => k -> v.map(_._2).sum }

but generally below code works for everything even if keys are different

Do groupby with first item in the tuple and then collapse the list which is the value of the resultant map after groupby

val list = Map("Mary")
list.groupBy(_._1).map { case (k, v) => v(0)._1 -> v.map(_._2).sum}

Scala REPL

 scala> val list = map("Mary")
 list: List[(String, Int)] = List(("Mary", 7065), ("Mary", 2604), ("Mary", 1414))

 scala> list.groupBy(_._1).map { case (k, v) => v(0)._1 -> v.map(_._2).sum}
 res11: Map[String, Int] = Map("Mary" -> 11083)

 scala> val map =  Map("Mary" -> List(("Mary", 7065), ("Mary", 2604), ("Mary", 1414)))
 map: Map[String, List[(String, Int)]] = Map("Mary" -> List(("Mary", 7065), ("Mary", 2604), ("Mary", 1414)))

 scala> val list = map("Mary")
 list: List[(String, Int)] = List(("Mary", 7065), ("Mary", 2604), ("Mary", 1414))

 scala> list.groupBy(_._1).map { case (k, v) => v(0)._1 -> v.map(_._2).sum}
 res14: Map[String, Int] = Map("Mary" -> 11083)

Upvotes: 1

easel
easel

Reputation: 4048

You group by the the key's, then fold on the values:

scala> val input = Map("Mary" -> List(("Mary", 1), ("Mary", 2), ("Mary", 3)))
res1: Iterable[scala.collection.immutable.Map[String,List[(String, Int)]]] = List(Map(Mary -> List((Mary,1), (Mary,2), (Mary,3))))

scala> input.values.map(_.groupBy(_._1).map { case (k, v) => (k -> v.map(_._2).foldLeft(0)(_ + _))})
res7: Iterable[scala.collection.immutable.Map[String,Int]] = List(Map(Mary -> 6))

Upvotes: 0

Related Questions