Caps
Caps

Reputation: 1523

Summing and grouping map values in Scala

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

Answers (1)

Travis Brown
Travis Brown

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

Related Questions