In Clojure the diff function can be applied to maps, that doesn't seem to be the case in Scala, is anyone aware of something in Scala that would make it more accessible to obtain what the Clojure diff function obtains when it is applied to maps?
Here's the Clojure diff function explained for reference.
http://clojuredocs.org/clojure_core/clojure.data/diff
This is equivalent to Clojure's diff
:
import collection.generic.CanBuildFrom
def diff[T, Col](x: Col with TraversableOnce[T], y: Col with TraversableOnce[T])
(implicit cbf: CanBuildFrom[Col, T, Col]): (Col, Col, Col) = {
val xs = x.toSet
val ys = y.toSet
def convert(s: Set[T]) = (cbf(x) ++= s).result
(convert(xs diff ys), convert(ys diff xs), convert(xs intersect ys))
}
It can operate on any kind of TraversableOnce
and will return results with the same type as its parameters:
scala> diff(Map(1 -> 2), Map(1 -> 2))
res35: (scala.collection.immutable.Map[Int,Int], scala.collection.immutable.Map[Int,Int], scala.collection.immutable.Map[Int,Int]) = (Map(),Map(),Map(1 -> 2))
As others have said there isn't something exactly like that, but you can build it anyways. Here's my attempt that is added on as a companion to the map class. It produces the same result as the clojure diff example.
object MapsDemo extends App{
implicit class MapCompanionOps[A,B](val a: Map[A,B]) extends AnyVal {
def diff(b: Map[A,B]): (Map[A,B],Map[A,B],Map[A,B]) = {
(a.filter(p => !b.exists(_ == p)), //things-only-in-a
b.filter(p => !a.exists(_ == p)), //things-only-in-b
a.flatMap(p => b.find(_ == p) )) //things-in-both
}
}
val uno = Map("same" ->"same","different" -> "one")
val dos = Map("same" ->"same","different" -> "two","onlyhere"->"whatever")
println(uno diff dos) //(Map(different -> one),Map(different -> two, onlyhere -> whatever),Map(same -> same))
println( Map("a"->1).diff(Map("a"->1,"b"->2)) ) //(Map(),Map(b -> 2),Map(a -> 1))
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With