Как объединить 2 параллельные карты, учитывая ассоциативную функцию

Каков наилучший способ объединить две карты, учитывая ассоциативную функцию, когда ключи присутствуют на обеих картах.

Вот моя текущая реализация

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 ответ

По какой-то причине является "параллельной картой"? Если нет, вы можете легко использовать scalaz

Ассоциативные функции для ключей аналогичны полугруппам: http://eed3si9n.com/learning-scalaz/Functor+Laws.html#Semigroup+Laws

И когда у вас есть полугруппа, доступная Map становится Monoid, и вы можете объединить их следующим образом:

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)

И результат:

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

Вы можете легко написать себе Monoid для параллельной карты, если вы не хотите преобразовывать их в неизменные карты, но конверсия почти бесплатна, поэтому я не понимаю, почему бы не использовать ее

licensed under cc by-sa 3.0 with attribution.