0

How can I merge maps like below:

val a = Map("a" -> 1, "b" -> 2)
val b = Map("b" -> 3, "c" -> 6)

after merge:

var c = Map("a" -> 1, "b" -> 5, "c" -> 6)
秦时明月
  • 35
  • 3
  • 8

1 Answers1

0
 val a = Map("a" -> 1, "b" -> 2) 
 val b = Map("b" -> 3, "c" -> 6)
 val c = a.map {
   case (key, value) => key -> (value + b.getOrElse(key, 0))
 } ++ b.filterKeys(bKey => !a.keySet.contains(bKey))

This should work but if it doesn't... I just found I think your question is a duplicate: Best way to merge two maps and sum the values of same key?

In there you see that other possible solutions are...

(map1.keySet ++ map2.keySet).map {i=> (i,map1.getOrElse(i,0) + map2.getOrElse(i,0))}.toMap


map1 ++ map2.map { case (k,v) => k -> (v + map1.getOrElse(k,0)) }

val m1 = Map(1 -> 1.0, 3 -> 3.0, 5 -> 5.2)
val m2 = Map(0 -> 10.0, 3 -> 3.0)
val merged = (m2 foldLeft m1) (
  (acc, v) => acc + (v._1 -> (v._2 + acc.getOrElse(v._1, 0.0)))
)

And more

Jordan Cutler
  • 562
  • 4
  • 14
  • It seems to work.But when I try to define this as a funcxtion, got erros as follows:error: overloaded method value + with alternatives: [INFO] (x: Double)Double [INFO] (x: Float)Float [INFO] (x: Long)Long [INFO] (x: Int)Long [INFO] (x: Char)Long [INFO] (x: Short)Long [INFO] (x: Byte)Long [INFO] (x: String)String [INFO] cannot be applied to (AnyVal) [INFO] a.map { case (key, value) => key -> (value + b.getOrElse(key, 0)) } ++ b.filterKeys(bKey => !a.keySet.contains(bKey)) – 秦时明月 Mar 28 '18 at 03:55
  • Can you copy and paste the code you are defining as a function – Jordan Cutler Mar 28 '18 at 03:56
  • This is the defination: val mergeMap = udf( (a:Map[String, Long], b:Map[String, Long]) => a.map { case (key, value) => key -> (value + b.getOrElse(key, 0)) } ++ b.filterKeys(bKey => !a.keySet.contains(bKey)) ) – 秦时明月 Mar 28 '18 at 04:02
  • `def mapMerge(map1: Map[String, Long], map2: Map[String, Long]): Map[String, Long] = { val map1Keys = map1.keySet map1.map { case (key, value) => key -> (value + map2.getOrElse(key, 0)) } ++ map2.filterKeys(map2Key => !map1Keys.contains(map2Key)) }` – Jordan Cutler Mar 28 '18 at 04:06
  • The same errors. It seems a type error. – 秦时明月 Mar 28 '18 at 04:17
  • `def mapMerge(map1: Map[String, Long], map2: Map[String, Long]): Map[String, Long] = { val map1Keys = map1.keySet map1.map { case (key, value) => key -> (value + map2.getOrElse(key, 0L)) } ++ map2.filterKeys(map2Key => !map1Keys.contains(map2Key)) }` Try now. The reason why was because there wasn't an L next to the 0, so it didn't know which + method to use – Jordan Cutler Mar 28 '18 at 04:20
  • 1
    yeah, it works! Thank you very much! – 秦时明月 Mar 28 '18 at 04:40
  • no problem :) ;;; – Jordan Cutler Mar 28 '18 at 04:41