如何比较Swift中的两个词典?

时间:2015-09-03 01:31:20

标签: swift dictionary compare

是否有一种简单的方法可以快速比较两个[String: AnyObject]词典,因为它不接受==运算符?

通过比较两个词典,我的意思是检查它们是否具有相同的确切键,并且对于每个键,它们具有相同的值。

4 个答案:

答案 0 :(得分:93)

正如Hot Licks已经提到的,您可以使用NSDictionary方法isEqualToDictionary()来检查它们是否相同如下:

let dic1: [String: AnyObject] = ["key1": 100, "key2": 200]
let dic2: [String: AnyObject] = ["key1": 100, "key2": 200]
let dic3: [String: AnyObject] = ["key1": 100, "key2": 250]

println( NSDictionary(dictionary: dic1).isEqualToDictionary(dic2) )   // true
println( NSDictionary(dictionary: dic1).isEqualToDictionary(dic3) )  // false

您还可以实现自定义运算符" =="如下:

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

println(dic1 == dic2)   // true
println(dic1 == dic3)   // false

Xcode 9•Swift 4

从文档中,字典现在被定义为结构:

struct Dictionary<Key : Hashable, Value> : Collection, ExpressibleByDictionaryLiteral
  

描述

     

一个集合,其元素是键值对。一个   dictionary是一种哈希表,提供快速访问   它包含的条目。表中的每个条目都使用它来标识   key,是一种可散列的类型,如字符串或数字。你用它   用于检索相应值的键,可以是任何对象。在   在其他语言中,类似的数据类型称为哈希或关联   阵列。使用字典文字创建新字典。一个   dictionary literal是逗号分隔的键值对列表   冒号将每个键与其相关值分开,包围   用方括号。您可以将字典文字分配给变量   或者常量或将其传递给需要字典的函数。

以下是如何创建HTTP响应代码及其相关消息的字典:

var responseMessages = [200: "OK",
                        403: "Access forbidden",
                        404: "File not found",
                        500: "Internal server error"]
  

推断responseMessages变量的类型为[Int: String]。   字典的密钥类型是Int,以及字典的值类型   字典是String

要创建没有键值对的字典,请使用空字典文字([:])。

var emptyDict: [String: String] = [:]

任何符合Hashable协议的类型都可以用作字典的Key类型,包括Swift的所有基本类型。您可以使用自己的自定义类型作为字典键,使其符合Hashable协议。

我们不再需要定义自定义运算符:

来自文档:

static func ==(lhs: [Key : Value], rhs: [Key : Value]) -> Bool

测试:

let dic1 = ["key1": 100, "key2": 200]
let dic2 = ["key1": 100, "key2": 200]
let dic3 = ["key1": 100, "key2": 250]

print(dic1 == dic2)   // true
print(dic1 == dic3)   // false

在上面的示例中,所有字典键和值都是相同的类型。 如果我们尝试比较两个类型[String: Any]的词典,Xcode会抱怨二元运算符==不能应用于两个[String: Any]个操作数。

    let dic4: [String: Any] = ["key1": 100, "key2": "200"]
    let dic5: [String: Any] = ["key1": 100, "key2": "200"]
    let dic6: [String: Any] = ["key1": 100, "key2": Date()]

    print(dic4 == dic5)  // Binary operator == cannot be applied to two `[String: Any]` operands

但是我们可以扩展实现中缀运算符的==运算符功能,将Swift Dictionary转换为NSDictionary并将字典值约束为Hashable Protocol:

public func ==<K, V: Hashable>(lhs: [K: V], rhs: [K: V] ) -> Bool {
    return (lhs as NSDictionary).isEqual(to: rhs)
}

测试:

let dic4: [String: AnyHashable] = ["key1": 100, "key2": "200"]
let dic5: [String: AnyHashable] = ["key1": 100, "key2": "200"]
let dic6: [String: AnyHashable] = ["key1": 100, "key2": Date()]
print(dic4 == dic5)   // true
print(dic4 == dic6)   // false

答案 1 :(得分:12)

Swift 4更新:

比较字典现在是原生的! (文件here

Swift 3:

Leo Dabus已经拥有一份出色的书面文章,其中包含已接受的解决方案。然而,对我来说,我发现它还需要一个步骤才能完全使用。正如您从代码中看到的那样,您需要将字典类型设置为[AnyHashable: Any],否则您将获得Binary operator '==' cannot be applied to two '[String : Any]' operands,以便在我的示例中使用反序列化JSON时常用的字典。

救援的泛型!:

// Swift 3.0
func == <K, V>(left: [K:V], right: [K:V]) -> Bool {
    return NSDictionary(dictionary: left).isEqual(to: right)
}

或在另一个案例中,[String: Any?]

func == <K, V>(left: [K:V?], right: [K:V?]) -> Bool {
    guard let left = left as? [K: V], let right = right as? [K: V] else { return false }
    return NSDictionary(dictionary: left).isEqual(to: right)
}

答案 2 :(得分:11)

在Swift 2中,当 KeyValue 都是Equatable时,您可以在字典本身上使用==

public func ==<Key : Equatable, Value : Equatable>(lhs: [Key : Value], rhs: [Key : Value]) -> Bool

而且,NSObject是Equatable:

public func ==(lhs: NSObject, rhs: NSObject) -> Bool

在您的情况下,如果您正在使用要使用isEqual:进行比较的Obj-C对象,则可以使用NSObject作为值类型(而不是AnyObject)。

答案 3 :(得分:0)

如果没有自定义类型的词典,在Swift 2+中,您可以使用==运算符来比较两个Dictionary,以检查它们是否相等。

但在某些情况下,将自定义类型作为Dictionary的值(例如struct),您必须采用Equatable才能使用该自定义类型{{ 1}} operator。

例如:

==

现在您可以使用// custom type struct Custom: Equatable { var value: Int } // MARK: adopting Equatable func ==(lhs: Custom, rhs: Custom) -> Bool { if lhs.value == rhs.value { return true } else { return false } } 运算符来比较两个词典:

==