Scala中如何合并Map并对相同Key的Value求和?
合并Scala Map并累加相同Key的Value
嘿,这个需求在Scala里有好几种优雅的实现方式,我给你列几个常用的方案:
方法一:使用foldLeft(兼容所有Scala版本)
这是最通用的写法,不管你用的是哪个Scala版本都能跑通。核心思路是把其中一个Map作为初始累加器,遍历另一个Map的键值对,逐个更新累加器里的对应值:
val a = Map("a" -> 1, "b" -> 2) val b = Map("b" -> 3, "c" -> 6) val mergedMap = b.foldLeft(a) { case (acc, (key, value)) => acc + (key -> acc.getOrElse(key, 0) + value) } // 结果:Map("a" -> 1, "b" -> 5, "c" -> 6)
解释:foldLeft以a为初始的累加器acc,每遍历b里的一个键值对,就取出acc中该key的现有值(如果没有就用0),加上当前value,再把新的键值对放回累加器里。
方法二:使用groupMapReduce(Scala 2.13+ 推荐)
Scala 2.13之后新增了groupMapReduce方法,用它可以一行代码搞定,写法更简洁直观:
val a = Map("a" -> 1, "b" -> 2) val b = Map("b" -> 3, "c" -> 6) val mergedMap = (a.toSeq ++ b.toSeq) .groupMapReduce(_._1)(_._2)(_ + _) // 结果:Map("a" -> 1, "b" -> 5, "c" -> 6)
解释:
- 先把两个Map转成Seq并合并,得到所有键值对的集合;
groupMapReduce第一步按key分组(_._1取键);- 第二步提取每个分组里的value(
_._2取值); - 第三步对每个分组里的value执行累加操作(
_ + _)。
方法三:结合++和map实现
这种写法也很直观,先处理b的所有键值对,把每个key对应的value和a里的对应值相加,再和a合并:
val a = Map("a" -> 1, "b" -> 2) val b = Map("b" -> 3, "c" -> 6) val mergedMap = a ++ b.map { case (key, value) => key -> (a.getOrElse(key, 0) + value) } // 结果:Map("a" -> 1, "b" -> 5, "c" -> 6)
解释:b.map会把b的每个key对应的value转换成“a里的对应值+当前value”,然后用++把处理后的b和a合并——因为++是后面的集合覆盖前面的重复key,所以刚好能保留相加后的结果。
内容的提问来源于stack exchange,提问作者秦时明月
相关产品推荐
相关产品推荐

