0

What is the best way to merge two maps, given an associative function when keys are present in both maps.

Here is my current implementation

private def mergeMap[A, B](map1: concurrent.Map[A, B], map2: concurrent.Map[A, B], f: (B, B) => B) : concurrent.Map[A, B] = {
  val keys = map1.keys ++ map2.keys
  val newMap = new TrieMap[A, B]()
  keys.foreach { k =>
    (map1.get(k), map2.get(k)) match {
      case (Some(v1), Some(v2)) => newMap.put(k, f(v1, v2))
      case (Some(v1), None) => newMap.put(k, v1)
      case (None, Some(v2)) => newMap.put(k, v2)
      case _ => // could not happen
    }
  }
  newMap
}

1 Answer 1

2

Is 'concurrent map' a requirement for some reason? If not you can easily use scalaz

Associative functions for keys is the same as Semigroup: http://eed3si9n.com/learning-scalaz/Functor+Laws.html#Semigroup+Laws

And when you have semigroup available Map becomes Monoid and you can merge them like this:

  import scala.collection.concurrent

  import scalaz._
  import Scalaz._

  val map1 = concurrent.TrieMap("a" -> 1, "b" -> 1)
  val map2 = concurrent.TrieMap("b" -> 1, "c" -> 1)

  val merge = map1.toMap |+| map2.toMap

  println(merge)

And result is:

  Map(c -> 1, b -> 2, a -> 1)

You can pretty easy write you own Monoid for concurrent map if you don't want convert them to immutable maps, but conversion is almost free, so I don't see why not to use it

3
  • How do you specify the tie-breaker function f here?.
    – Kulu Limpa
    Commented Nov 3, 2014 at 22:56
  • 1
    You mean associative function f: (B, B) => B? If so in this particular case B is Int and Semigroup for numbers already defined in scope by scalaz implicates Commented Nov 3, 2014 at 23:11
  • Yes, I was talking about the associative function; sorry for the confusion. I was just wondering how |+| magically knew what to do in case a key is defined in both maps and how this behavior could be specified. So appearantly you define an implicit val of type Semigroup[B] and override the append function to f. Thanks for the explanation. Your solution is definitively interesting.
    – Kulu Limpa
    Commented Nov 3, 2014 at 23:48

Not the answer you're looking for? Browse other questions tagged or ask your own question.