val map1 = Map(1 -> 9 , 2 -> 20)
val map2 = Map(1 -> 100, 3 -> 300)
Я хочу объединить их и просуммировать значения тех же ключей. Итак, результат будет:
Map(2->20, 1->109, 3->300)
Теперь у меня есть 2 решения:
val list = map1.toList ++ map2.toList
val merged = list.groupBy ( _._1) .map { case (k,v) => k -> v.map(_._2).sum }
и
val merged = (map1 /: map2) { case (map, (k,v)) =>
map + ( k -> (v + map.getOrElse(k, 0)) )
}
Но я хочу знать, есть ли какие-нибудь лучшие решения.
Используя typeclass шаблон, мы можем объединить любой Числовой тип:
object MapSyntax {
implicit class MapOps[A, B](a: Map[A, B]) {
def plus(b: Map[A, B])(implicit num: Numeric[B]): Map[A, B] = {
b ++ a.map { case (key, value) => key -> num.plus(value, b.getOrElse(key, num.zero)) }
}
}
}
Использование:
import MapSyntax.MapOps
map1 plus map2
Слияние последовательности карт:
maps.reduce(_ plus _)