Reputation: 1523
I'm a newbie to Scala and I'm looking for a more succinct way to sum and group map values. Is there a better way than the following code:
def mapSum(thisMap: Map[Char, Int], thatMap: Map[Char, Int]) = {
thisMap.transform { (k, v) => thatMap(k) + v }
}
Which would satisfy the following test:
@Test
def mapSum() {
val map: Map[Char, Int] = Map('C' -> 1, 'D' -> 3)
val newMap = mapSum(map, map)
assertEquals(2, newMap('C'))
assertEquals(6, newMap('D'))
}
Upvotes: 2
Views: 685
Reputation: 139038
If you're going for succinct, you're not going to get much better than your current version with the standard library (although note that you can drop the outer brackets to make it a two-liner).
Scalaz provides some tools that can make this kind of thing a little more concise, including a monoid instance for Map
and a pimped unionWith
method:
scala> import scalaz._, Scalaz._
import scalaz._
import Scalaz._
scala> val m = Map('C' -> 1, 'D' -> 3)
m: scala.collection.immutable.Map[Char,Int] = Map(C -> 1, D -> 3)
scala> m |+| m
res0: scala.collection.immutable.Map[Char,Int] = Map(C -> 2, D -> 6)
scala> (m unionWith m)(_ + _)
res1: Map[Char,Int] = Map(C -> 2, D -> 6)
Note that both of these approaches behave a little differently than yours, though—they don't choke at runtime if there are keys in the first that aren't in the second, and they don't silently ignore keys in the second that aren't in the first.
Upvotes: 3