检测两个Map
实例之间的更改的最佳/最干净/最有效的方法是什么。即。
val before = Map(1 -> "foo", 2 -> "bar", 3 -> "baz")
val after = Map(1 -> "baz", 2 -> "bar", 4 -> "boo")
// not pretty:
val removed = before.keySet diff after.keySet
val added = after.filterNot { case (key, _) => before contains key }
val changed = (before.keySet intersect after.keySet).flatMap { key =>
val a = before(key)
val b = after (key)
if (a == b) None else Some(key -> (a, b))
}
答案 0 :(得分:1)
这是一个想法。它可能需要O(N * log N),其中N = max(before.size,after.size):
sealed trait Change[+K, +V]
case class Removed[K ](key: K) extends Change[K, Nothing]
case class Added [K, V](key: K, value : V) extends Change[K, V]
case class Updated[K, V](key: K, before: V, after: V) extends Change[K, V]
def changes[K, V](before: Map[K, V], after: Map[K, V]): Iterable[Change[K, V]] ={
val b = Iterable.newBuilder[Change[K, V]]
before.foreach { case (k, vb) =>
after.get(k) match {
case Some(va) if vb != va => b += Updated(k, vb, va)
case None => b += Removed(k)
case _ =>
}
}
after.foreach { case (k, va) =>
if (!before.contains(k)) b += Added(k, va)
}
b.result()
}
changes(before, after).foreach(println)
// Updated(1,foo,baz)
// Removed(3)
// Added(4,boo)