val map1 = Map(1 -> 9 , 2 -> 20)
val map2 = Map(1 -> 100, 3 -> 300)
I want to merge them, and sum the values of same keys. So the result will be:
Map(2->20, 1->109, 3->300)
Now I have 2 solutions:
val list = map1.toList ++ map2.toList
val merged = list.groupBy ( _._1) .map { case (k,v) => k -> v.map(_._2).sum }
and
val merged = (map1 /: map2) { case (map, (k,v)) =>
map + ( k -> (v + map.getOrElse(k, 0)) )
}
But I want to know if there are any better solutions.
The shortest answer I know of that uses only the standard library is
You can also do that with Cats.
I've got a small function to do the job, it's in my small library for some frequently used functionality which isn't in standard lib. It should work for all types of maps, mutable and immutable, not only HashMaps
Here is the usage
https://github.com/jozic/scalax-collection/blob/master/README.md#mergedwith
And here's the body
https://github.com/jozic/scalax-collection/blob/master/src%2Fmain%2Fscala%2Fcom%2Fdaodecode%2Fscalax%2Fcollection%2Fextensions%2Fpackage.scala#L190
Well, now in scala library (at least in 2.10) there is something you wanted - merged function. BUT it's presented only in HashMap not in Map. It's somewhat confusing. Also the signature is cumbersome - can't imagine why I'd need a key twice and when I'd need to produce a pair with another key. But nevertheless, it works and much cleaner than previous "native" solutions.
Also in scaladoc mentioned that
I wrote a blog post about this , check it out :
http://www.nimrodstech.com/scala-map-merge/
basically using scalaz semi group you can achieve this pretty easily
would look something like :
This can be implemented as a Monoid with just plain Scala. Here is a sample implementation. With this approach, we can merge not just 2, but a list of maps.
The Map based implementation of the Monoid trait that merges two maps.
Now, if you have a list of maps that needs to be merged (in this case, only 2), it can be done like below.