val map1 = Map(1 -> 9 , 2 -> 20)
val map2 = Map(1 -> 100, 3 -> 300)
我想合并它们,并将相同键的值相加。因此,结果将是:
Map(2->20, 1->109, 3->300)
现在我有两个解决方案:
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)) )
}
但我想知道有没有更好的解决方案。
发布于 2011-08-16 22:58:36
据我所知,只使用标准库的最简短的答案是
map1 ++ map2.map{ case (k,v) => k -> (v + map1.getOrElse(k,0)) }
发布于 2011-08-16 18:16:50
快速解决方案:
(map1.keySet ++ map2.keySet).map {i=> (i,map1.getOrElse(i,0) + map2.getOrElse(i,0))}.toMap
发布于 2016-04-27 12:25:57
只需使用普通的Scala就可以将其实现为Monoid。下面是一个示例实现。使用这种方法,我们可以合并的不只是2个,而是一个映射列表。
// Monoid trait
trait Monoid[M] {
def zero: M
def op(a: M, b: M): M
}
合并两个地图的Monoid特征的基于地图的实现。
val mapMonoid = new Monoid[Map[Int, Int]] {
override def zero: Map[Int, Int] = Map()
override def op(a: Map[Int, Int], b: Map[Int, Int]): Map[Int, Int] =
(a.keySet ++ b.keySet) map { k =>
(k, a.getOrElse(k, 0) + b.getOrElse(k, 0))
} toMap
}
现在,如果您有一个需要合并的map列表(在本例中,只有2个),可以像下面这样完成。
val map1 = Map(1 -> 9 , 2 -> 20)
val map2 = Map(1 -> 100, 3 -> 300)
val maps = List(map1, map2) // The list can have more maps.
val merged = maps.foldLeft(mapMonoid.zero)(mapMonoid.op)
https://stackoverflow.com/questions/7076128
复制相似问题