I can compare whether 2 dictionaries match or not like this:
func ==(lhs: [String: AnyObject], rhs: [String: AnyObject] ) -> Bool {
return NSDictionary(dictionary: lhs).isEqualToDictionary(rhs)
}
Is there a concise way to extract the differences between 2 dictionaries, as in the opposite of the intersection?
With set. Here we take two dictionaries and apply set function to them. Then we subtract the two sets to get the difference. We do it both ways, by subtracting second dictionary from first and next subtracting first dictionary form second.
Using == operator to Compare Two Dictionaries Here we are using the equality comparison operator in Python to compare two dictionaries whether both have the same key value pairs or not.
Use == to check equality of two dictionaries Use == to check if two dictionaries contain the same set of key: value pairs.
We can define an operator to check whether 2 dictionaries contains the same keys and for each key the same value.
First of all we need to use generics to require that the Value
of the dictionaries conforms to Equatable
otherwise we won't be able to compare the values.
Here's the code
func ==<Value:Equatable>(left: [String: Value], right: [String: Value]) -> Bool {
guard left.keys.count == right.keys.count else { return false }
let differenceFound = zip(left.keys.sort(), right.keys.sort()).contains { elm -> Bool in
let leftKey = elm.0
let rightKey = elm.1
return leftKey != rightKey || left[leftKey] != right[rightKey]
}
return !differenceFound
}
The first line verify that the dictionaries have the same number of entries, otherwise false
is returned.
The next block of code sort the keys of both dictionaries and compare each pair looking for a pair where the keys or the values are different.
If such difference is not found then the dictionaries have the same keys and values, so they are equals.
["a":1, "b": 2] == ["a":1, "b": 2] // true
Of course since values inside a dictionaries don't have an order the following is still true
["a":1, "b": 2] == ["b":2, "a": 1] // true
In the next example we compare 2 dictionaries with a different number of values
["a":1, "b": 2] == ["a":1, "b": 2, "c": 3] // false
Since we defined the ==
operator, Swift gifts us the !=
operator (which simply returns the opposite of ==
), so we can also write
["a":1, "b": 2] != ["d":4] // true
The same operator can also be written in this shorter way
func ==<Value:Equatable>(left: [String: Value], right: [String: Value]) -> Bool {
return
left.keys.count == right.keys.count &&
!zip(left.keys.sort(), right.keys.sort()).contains { $0 != $1 || left[$0] != right[$1] }
}
Now given 2 dictionaries a
and b
, you want to perform a.minus(b)
and get as result a new dictionaries containing all the (key, value)
pairs available in a
and not available in b
.
Here's the code
extension Dictionary where Key: Comparable, Value: Equatable {
func minus(dict: [Key:Value]) -> [Key:Value] {
let entriesInSelfAndNotInDict = filter { dict[$0.0] != self[$0.0] }
return entriesInSelfAndNotInDict.reduce([Key:Value]()) { (res, entry) -> [Key:Value] in
var res = res
res[entry.0] = entry.1
return res
}
}
}
Examples
["a":1].minus(["a":2]) // ["a": 1]
["a":1].minus(["a":1]) // [:]
["a":1].minus(["a":1, "b":2]) // [:]
["a":1, "b": 2].minus(["a":1]) // ["b": 2]
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