我可以通过以下方式比较两个字典是否匹配:
func ==(lhs: [String: AnyObject], rhs: [String: AnyObject] ) -> Bool {
return NSDictionary(dictionary: lhs).isEqualToDictionary(rhs)
}
是否有一种简洁的方法可以提取两个字典之间的差异,就像反向交集一样?
我可以通过以下方式比较两个字典是否匹配:
func ==(lhs: [String: AnyObject], rhs: [String: AnyObject] ) -> Bool {
return NSDictionary(dictionary: lhs).isEqualToDictionary(rhs)
}
是否有一种简洁的方法可以提取两个字典之间的差异,就像反向交集一样?
我们可以定义一个运算符来检查两个字典是否包含相同的键以及对于每个键是否具有相同的值。
首先,我们需要使用泛型来要求字典的Value
符合Equatable
,否则我们将无法比较这些值。
以下是代码:
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
}
第一行验证字典的条目数是否相同,如果不同则返回 false
。
下一个代码块对两个字典的键进行排序,并比较每一对键,寻找其中键或值不同的情况。
如果没有发现这样的差异,则说明两个字典具有相同的键和值,因此它们相等。
["a":1, "b": 2] == ["a":1, "b": 2] // true
当然,由于字典内的值没有顺序,因此以下内容仍然是正确的。
["a":1, "b": 2] == ["b":2, "a": 1] // true
在下一个示例中,我们将比较具有不同数量值的两个字典
["a":1, "b": 2] == ["a":1, "b": 2, "c": 3] // false
既然我们定义了==
运算符,Swift还提供了!=
运算符(它只是返回==
的相反结果),因此我们也可以写成
["a":1, "b": 2] != ["d":4] // true
同一个操作符也可以用这种更短的方式来书写
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] }
}
现在给定两个字典 a
和 b
,你想执行 a.minus(b)
并获得一个新的字典,其中包含所有在 a
中可用且不在 b
中可用的 (key, value)
对。
这是代码:
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
}
}
}
例子
["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]
let dict0 = ["a":1]
和 let dict1= ["b":2]
。difference 方法应该返回什么? - Luca Angeletti["a": 1, "b": 2]
- TruMan1["a":1, "b": 2, "c": 3].difference(["b": 2, "c": 4]) => ["a": 1, "c": 3]
。 - TruMan1(key,value)
对,而不是第二个字典中的。 - Luca Angeletti