我如何比较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中,当Key
和Value
都是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") }