我如何比较Swift中的两个字典?

有没有一种简单的方法来比较两个[String: AnyObject]字典在swift中,因为它不接受==运算符?

通过比较两个字典,我的意思是检查他们有相同的确切键和每个键他们有相同的值。

正如已经提到的热舔你可以使用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 8 beta 6•Swift 3

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

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

描述

元素是键值对的集合。 字典是一种散列表,可以快速访问它所包含的条目。 表中的每个条目都使用其密钥来标识,该密钥是可排列的types,如string或数字。 您可以使用该键来检索相应的值,该值可以是任何对象。 在其他语言中,类似的数据types被称为散列或关联数组。 通过使用字典文字创build一个新的字典。 字典文字是键值对的逗号分隔列表,其中冒号将每个键与其相关值分隔开,并用方括号括起来。 您可以将字典文字分配给variables或常量,或将其传递给需要字典的函数。

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

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

responseMessagesvariables被推断为具有types[Int: String] 。 字典的键types是Int ,字典的Valuetypes是String

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

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

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


我们不需要定义一个自定义的操作符:

从文档:

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

testing:

 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 

在上面的例子中,所有的字典键和值都是相同的types。 如果我们尝试比较[String: Any]types的两个字典,Xcode会抱怨Binary operator ==不能应用于两个[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 

但是我们可以使用NSDictionary初始化器来扩展==运算符的function:

 convenience init(dictionary otherDictionary: [AnyHashable : Any]) 

 public func ==(lhs: [AnyHashable: Any], rhs: [AnyHashable: Any] ) -> Bool { return NSDictionary(dictionary: lhs).isEqual(to: rhs) } 

testing:

 let dic4: [AnyHashable: Any] = ["key1": 100, "key2": "200"] let dic5: [AnyHashable: Any] = ["key1": 100, "key2": "200"] let dic6: [AnyHashable: Any] = ["key1": 100, "key2": Date()] print(type(of:dic4),type(of:dic5),type(of:dic6)) // Dictionary<AnyHashable, Any> Dictionary<AnyHashable, Any> Dictionary<AnyHashable, Any> print(dic4 == dic5) // true print(dic4 == dic6) // false 

在Swift 2中,当KeyValue都是Equatable ,你可以在字典上使用==

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

而且,NSObject是可衡量的:

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

在你的情况下,如果你正在使用isEqual:来处理Obj-C对象,你可以简单地使用NSObject作为你的值types(而不是AnyObject)。

利奥达布斯已经有了一个出色的书面职位,接受的解决scheme。 但是,对于我来说,我发现它需要更多的步骤才能充分利用。 正如你从他的代码中可以看到的,你需要将你的字典types设置为[AnyHashable: Any] ,否则你将得到Binary operator '==' cannot be applied to two '[String : Any]' operands [AnyHashable: Any]使用在我的例子反序列化JSON常见字典。

generics救援!:

 // 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) } 

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

但在一些使用自定义types作为Dictionary的值(比如struct )的情况下,您必须使用Equatable才能使该自定义types使用==运算符。

例如:

 // 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 } } 

现在,您可以使用==运算符来比较两个字典:

 let dic3: [String: Custom] = ["key1": Custom(value:1), "key2": Custom(value:2)] let dic4: [String: Custom] = ["key1": Custom(value:1), "key2": Custom(value:2)] if (dic3 == dic4) { print("equal") } else { print("not equal") }