From 2 lists of the form List[(Int, String)
:
l1 = List((1,\"a\"),(3,\"b\"))
l2 = List((3,\"a\"),(4,\"c\"))
how can I combine t
An alternative to Miles Sabin's answer using Scala 2.13
's new groupMapReduce method which is (as its name suggests) an equivalent (more efficient) of a groupBy
followed by mapValues
and a reduce
step:
(l1 ::: l2).groupMapReduce(_._2)(_._1)(_ + _).toList.map(_.swap)
// List[(Int, String)] = List((3,b), (4,a), (4,c))
This:
prepends l1
to l2
group
s elements based on their second tuple part (group part of groupMapReduce)
map
s grouped values to their first tuple part (map part of groupMapReduce)
reduce
s values (_ + _
) by summing them (reduce part of groupMapReduce)
and finally swap
s tuples' parts.
This is an equivalent version performed in one pass (for the group/map/reduce part) through the List of:
(l1 ::: l2).groupBy(_._2).mapValues(_.map(_._1).reduce(_ + _)).toList.map(_.swap)
With Scalaz, this is a snap.
import scalaz._
import Scalaz._
val l3 = (l1.map(_.swap).toMap |+| l2.map(_.swap).toMap) toList
The |+|
method is exposed on all types T
for which there exists an implementation of Semigroup[T]
. And it just so happens that the semigroup for Map[String, Int]
is exactly what you want.