如何提取字典之间的差异?

Posted

技术标签:

【中文标题】如何提取字典之间的差异?【英文标题】:How to extract differences between dictionaries? 【发布时间】:2016-08-09 23:03:59 【问题描述】:

我可以像这样比较两个字典是否匹配:

func ==(lhs: [String: AnyObject], rhs: [String: AnyObject] ) -> Bool 
    return NSDictionary(dictionary: lhs).isEqualToDictionary(rhs)

有没有一种简洁的方法来提取两个字典之间的差异,就像在交集的对面一样?

【问题讨论】:

具体有什么区别?给定两个字典,每个字典都可能有另一个字典中没有的键。对于两者中都存在的键,它们可能具有不同的值。这为您提供了两组可能的键以及一组可能的不同值。 是的,如果一个键不存在于另一个中,那么它会被认为是不同的。 【参考方案1】:

我们可以定义一个运算符来检查两个字典是否包含相同的键以及每个键是否具有相同的值。

值必须是相等的

首先我们需要使用泛型来要求字典的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

在下一个示例中,我们将 2 个字典与不同数量的值进行比较

["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] 

更新

现在给定 2 个字典 ab,您想要执行 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]

【讨论】:

我试图找出不同之处,所以也许是这样的扩展? extension Dictionary where Key: NSObject, Value:AnyObject func difference(other: [NSObject: AnyObject]) -&gt; [NSObject: AnyObject] ... 。因此,这将与交互作用相反或过滤差异。 @TruMan1:一个问题。给定这两个字典let dict0 = ["a":1]let dict1 = ["b":2]。差异方法应该返回什么? 好问题:["a": 1, "b": 2] 或者另一个例子:["a":1, "b": 2, "c": 3].difference(["b": 2, "c": 4]) =&gt; ["a": 1, "c": 3] @TomHarrington:我认为他想要第一本字典中的所有 (key,value) 对,而不是第二本字典。【参考方案2】:

Swift supports operations like symmetricDifference(:) and subtracting(:),但用于集合,而不是字典。根据您的需要,您可以区分键,然后使用 map 重建结果字典。

【讨论】:

以上是关于如何提取字典之间的差异?的主要内容,如果未能解决你的问题,请参考以下文章

从视频中提取图像,将其更改为灰度并找出差异

在OpenCV Python中检测/提取图像之间的最大差异

如何从 Python 中的字典中提取所有值?

R语言psych包的fa函数对指定数据集进行因子分析(输入数据为相关性矩阵)指定进行正交旋转斜交旋转提取因子比较正交旋转和斜交旋转之间的差异因子结构矩阵因子模式矩阵和因子相关矩阵之间的关系

如何从字典中提取仅打印某些变量python

如何在字典中提取特定值(仅包含其键的值)