Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 在两个映射之间生成更改集_Scala_Scala Collections - Fatal编程技术网

Scala 在两个映射之间生成更改集

Scala 在两个映射之间生成更改集,scala,scala-collections,Scala,Scala Collections,检测两个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

检测两个
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))
}

这里有一个想法。可能需要O(N*logn)和N=max(在.size之前,在.size之后):


作为一种非常普遍的方法,您可能有兴趣了解Wie?像我们的议长穆蒂?SchockThat看起来是对的,但它是
O(N)+O(M*logm)
其中
M
是变更集的大小。@RexKerr如果我之前有
。foreach
外部(O(N))并在之后调用
。获取
内部(O(logn)),这已经是O(N*logn),对吗?对于M,您正在使用带有
O(logn)
get的映射?然后你可以使用一个排序映射你的其他操作保持相同的顺序,但是你可以在
O(N)
中通过迭代来实现。对,我没有注意到hash-map-get是常量:-O
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)