13

Given the following list of tuples...

val list = List((1, 2), (1, 2), (1, 2))

... how do I sum all the values and obtain a single tuple like this?

(3, 6)
Mario Galic
  • 47,285
  • 6
  • 56
  • 98
j3d
  • 9,492
  • 22
  • 88
  • 172
  • 3
    Note that if you're using Scalaz you automatically get monoid instances for tuples whose elements have monoid instances, so you can just write `list.suml`. – Travis Brown May 10 '15 at 18:50

6 Answers6

22

Using the foldLeft method. Please look at the scaladoc for more information.

scala> val list = List((1, 2), (1, 2), (1, 2))
list: List[(Int, Int)] = List((1,2), (1,2), (1,2))

scala> list.foldLeft((0, 0)) { case ((accA, accB), (a, b)) => (accA + a, accB + b) }
res0: (Int, Int) = (3,6)

Using unzip. Not as efficient as the above solution. Perhaps more readable.

scala> list.unzip match { case (l1, l2) => (l1.sum, l2.sum) }
res1: (Int, Int) = (3,6) 
Lomig Mégard
  • 1,828
  • 14
  • 18
11

Very easy: (list.map(_._1).sum, list.map(_._2).sum).

2

You can solve this using Monoid.combineAll from the cats library:

import cats.instances.int._ // For monoid instances for `Int`
import cats.instances.tuple._  // for Monoid instance for `Tuple2`
import cats.Monoid.combineAll

  def main(args: Array[String]): Unit = {

    val list = List((1, 2), (1, 2), (1, 2))

    val res = combineAll(list)

    println(res)
    // Displays
    // (3, 6)
  }

You can see more about this in the cats documentation or Scala with Cats.

Valy Dia
  • 2,781
  • 2
  • 12
  • 32
1

answering to this question while trying to understand aggregate function in spark

scala> val list = List((1, 2), (1, 2), (1, 2))
list: List[(Int, Int)] = List((1,2), (1,2), (1,2))

   scala>  list.aggregate((0,0))((x,y)=>((y._1+x._1),(x._2+y._2)),(x,y)=>(x._1+y._2,y._2+x._2))
res89: (Int, Int) = (3,6)

Here is the link to the SO QA that helped to understand and answer this [Explain the aggregate functionality in Spark

1

Scalaz solution (suggestied by Travis and for some reason a deleted answer):

import scalaz._
import Scalaz._

val list = List((1, 2), (1, 2), (1, 2))
list.suml

which outputs

res0: (Int, Int) = (3,6)
Mario Galic
  • 47,285
  • 6
  • 56
  • 98
0

You can also use a reduce function :

val list = List((1, 2), (1, 2), (1, 2))

val res = list.reduce((x, y) => (x._1 + y._1, x._2 + y._2))
Emmanuel H
  • 82
  • 8