15

Is there any pre-defined function that I can use to compare two Maps based on the key and give me the difference? Right now, I iterate Map1 and foreach key, I check if there is an element in Map2 and I pattern match to find the difference. Is there a much elegant way to do this?

elm
  • 20,117
  • 14
  • 67
  • 113
joesan
  • 13,963
  • 27
  • 95
  • 232
  • show you code of pattern matching – Govind Singh Jul 18 '14 at 14:56
  • Similar to [this question](https://stackoverflow.com/questions/24580391/generating-change-set-between-two-maps/24580496), although that doesn't have a good answer yet. – 0__ Jul 18 '14 at 23:16

4 Answers4

26

Consider the difference between the maps converted into sets of tuples,

(m1.toSet diff m2.toSet).toMap
elm
  • 20,117
  • 14
  • 67
  • 113
  • 5
    Bear in mind the output that you'd get from the diff method will vary depending on which object you call the diff method on i.e. m2.toSet diff m1.toSet would produce a different result. – anton4o Sep 13 '16 at 08:34
12

Try:

val diff = (m1.keySet -- m2.keySet) ++ (m2.keySet -- m1.keySet)

diff contains the elements that are in m1 and not in m2 and that are in m2 and not in m1.

Jean Logeart
  • 52,687
  • 11
  • 83
  • 118
  • `--` is deprecated in 2.9 and I think removed from 2.10, you should use `m1.keySet.filterNot(m2.keySet)` – samthebest Jul 21 '14 at 18:30
  • really? it is in 2.11.5: http://www.scala-lang.org/api/2.11.5/index.html#scala.collection.immutable.Map – RoberMP May 28 '15 at 19:35
5

This solution looks like right way:

scala> val x = Map(1 -> "a", 2 -> "b", 3 -> "c")
x: scala.collection.immutable.Map[Int,String] = Map(1 -> a, 2 -> b, 3 -> c)

scala> val y = Map(1 -> "a", 2 -> "b", 4 -> "d")
y: scala.collection.immutable.Map[Int,String] = Map(1 -> a, 2 -> b, 4 -> d)

scala> val diff : Map[Int, String] = x -- y.keySet
diff: Map[Int,String] = Map(3 -> c)

Found it here https://gist.github.com/frgomes/69068062e7849dfe9d5a53bd3543fb81

Nikita Zonov
  • 51
  • 1
  • 2
2

I think the -- operator will do what you're looking for: http://www.scala-lang.org/api/current/index.html#scala.collection.Map@--(xs:scala.collection.GenTraversableOnce[A]):Repr

Although this will probably only work given the assumption that Map2 is always a subset of Map1...

Nate Whittaker
  • 1,866
  • 15
  • 14