比较Swift 4中的两个[String:Any]词典

时间:2017-12-04 11:24:25

标签: ios nsdictionary swift4

我有两个字典作为[String: Any]类型的文本属性工作,为了切换所需属性的ON或OFF,我需要检查两个字典是否相同。

我尝试了以下内容:

let current = inputTextView.typingAttributes

let undo = current.elementsEqual(attributes, by: { (arg0, arg1) -> Bool in
    return ((arg0.key == arg1.key) && (arg0.value == arg1.value))
})

但是在第二次评估中我得到了错误:

  

二元运算符'=='不能应用于两个'任意'操作数

比较两个类型为[String: Any]

字典的最佳方法是什么?

谢谢

2 个答案:

答案 0 :(得分:2)

Any不符合Equatable协议。如果使用==运算符,它是类型必须的。因此,您需要使用this answer中提到的带有类型参数的函数来比较Any个对象:

func isEqual<T: Equatable>(type: T.Type, a: Any, b: Any) -> Bool? {
    guard let a = a as? T, let b = b as? T else { return nil }
    return a == b
}

但是,要使用此功能,您应该知道typingAttributes中每个值的确切类型。您可以使用Mirror结构实现此目的,如下所示:

let lilAny: Any = "What's my type? :("
print(Mirror(reflecting: lilAny).subjectType) // String

答案 1 :(得分:0)

详细信息

  • Xcode版本10.2.1(10E1001),Swift 5

解决方案

import Foundation

func areEqual (_ left: Any, _ right: Any) -> Bool {
    if  type(of: left) == type(of: right) &&
        String(describing: left) == String(describing: right) { return true }
    if let left = left as? [Any], let right = right as? [Any] { return left == right }
    if let left = left as? [AnyHashable: Any], let right = right as? [AnyHashable: Any] { return left == right }
    return false
}

extension Array where Element: Any {

    static func == (left: [Element], right: [Element]) -> Bool {
        if left.count != right.count { return false }
        for (index, leftValue) in left.enumerated() {
            guard areEqual(leftValue, right[index]) else { return false }
        }
        return true
    }

    static func != (left: [Element], right: [Element]) -> Bool {
        return !(left == right)
    }
}
extension Dictionary where Value: Any {

    static func == (left: [Key : Value], right: [Key : Value]) -> Bool {
        if left.count != right.count { return false }
        for element in left {
            guard   let rightValue = right[element.key],
                    areEqual(rightValue, element.value) else { return false }
        }
        return true
    }

    static func != (left: [Key : Value], right: [Key : Value]) -> Bool {
        return !(left == right)
    }
}

用法

let comparisonResult = ["key1": 1, 2: "Value2"] == ["key1": ["key2":2]]     // false
print("!!!! \(comparisonResult)")

一些测试

func test(dict1: [AnyHashable : Any], dict2:  [AnyHashable : Any]) {
    print("========================")
    print("dict1: \(dict1)")
    print("dict2: \(dict2)")
    print("are\(dict1 == dict2 ? " " : " not ")equal")
}

test(dict1: ["key1": 1, 2: "Value2"],
     dict2: ["key1": 1, 2: "Value2"])

test(dict1: ["key1": 1, 2: "Value2"],
     dict2: ["key1": 1])

test(dict1: [2: "Value2"],
     dict2: ["key1": 1])

test(dict1: ["1": 1],
     dict2: [1: 1])

test(dict1: [1: 2],
     dict2: [1: 3])

test(dict1: ["key1": [1,2,3,4]],
     dict2: ["key1": [1,2,3,4]])

test(dict1: ["key1": [1,2,3,4]],
     dict2: ["key1": [1,2,3,"4"]])

test(dict1: ["key1": ["key2":2]],
     dict2: ["key1": ["key2":2]])

test(dict1: ["key1": ["key2":2]],
     dict2: ["key1": ["key2":3]])

test(dict1: ["key1": ["key2":2]],
     dict2: ["key1": ["key2":3]])

test(dict1: ["key1": [1,2,3,4] as [Any]],
     dict2: ["key1": [1,2,3,4] as [Int]])

test(dict1: ["key1":[1: "key1"] as [AnyHashable: Any]],
     dict2: ["key1":[1: "key1"] as [AnyHashable: String]])

test(dict1: ["key1":[1: "key1"] as [AnyHashable: Any]],
     dict2: ["key1":[2: "key1"] as [AnyHashable: String]])

测试结果

========================
dict1: [AnyHashable("key1"): 1, AnyHashable(2): "Value2"]
dict2: [AnyHashable("key1"): 1, AnyHashable(2): "Value2"]
are equal
========================
dict1: [AnyHashable("key1"): 1, AnyHashable(2): "Value2"]
dict2: [AnyHashable("key1"): 1]
are not equal
========================
dict1: [AnyHashable(2): "Value2"]
dict2: [AnyHashable("key1"): 1]
are not equal
========================
dict1: [AnyHashable("1"): 1]
dict2: [AnyHashable(1): 1]
are not equal
========================
dict1: [AnyHashable(1): 2]
dict2: [AnyHashable(1): 3]
are not equal
========================
dict1: [AnyHashable("key1"): [1, 2, 3, 4]]
dict2: [AnyHashable("key1"): [1, 2, 3, 4]]
are equal
========================
dict1: [AnyHashable("key1"): [1, 2, 3, 4]]
dict2: [AnyHashable("key1"): [1, 2, 3, "4"]]
are not equal
========================
dict1: [AnyHashable("key1"): ["key2": 2]]
dict2: [AnyHashable("key1"): ["key2": 2]]
are equal
========================
dict1: [AnyHashable("key1"): ["key2": 2]]
dict2: [AnyHashable("key1"): ["key2": 3]]
are not equal
========================
dict1: [AnyHashable("key1"): ["key2": 2]]
dict2: [AnyHashable("key1"): ["key2": 3]]
are not equal
========================
dict1: [AnyHashable("key1"): [1, 2, 3, 4]]
dict2: [AnyHashable("key1"): [1, 2, 3, 4]]
are equal
========================
dict1: [AnyHashable("key1"): [AnyHashable(1): "key1"]]
dict2: [AnyHashable("key1"): [AnyHashable(1): "key1"]]
are equal
========================
dict1: [AnyHashable("key1"): [AnyHashable(1): "key1"]]
dict2: [AnyHashable("key1"): [AnyHashable(2): "key1"]]
are not equal