有没有一种简单的方法来比较两个 [String: AnyObject]字典在快速,因为它不接受的 ==操作员?
[String: AnyObject]
==
通过比较两个字典,我的意思是检查它们具有相同的精确键,并且对于每个键,它们具有相同的值。
在 Swift 2中,当 ABC0和 Value是 Equatable时,你可以在字典本身上使用 ==:
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 作为您的值类型(而不是 AnyObject)。
isEqual:
正如 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
在 docs 中,dictionary 现在被定义为 struct:
struct Dictionary<Key : Hashable, Value> : Collection, ExpressibleByDictionaryLiteral
描述 其元素是键-值对的集合 Dictionary 是一种哈希表类型,提供对 表中的每个条目都使用其 Key,它是一个散列类型,如字符串或数字 键检索相应的值,该值可以是任何对象 其他语言中,类似的数据类型称为哈希表或关联数据类型 通过使用字典文字创建一个新的字典 字典常值是一个以逗号分隔的键值对列表,在 其中一个冒号将每个键与其相关联的值分开,被包围 可以将字典字面值赋给变量 或常数,或将其传递给需要字典的函数。
描述
其元素是键-值对的集合 Dictionary 是一种哈希表类型,提供对 表中的每个条目都使用其 Key,它是一个散列类型,如字符串或数字 键检索相应的值,该值可以是任何对象 其他语言中,类似的数据类型称为哈希表或关联数据类型 通过使用字典文字创建一个新的字典 字典常值是一个以逗号分隔的键值对列表,在 其中一个冒号将每个键与其相关联的值分开,被包围 可以将字典字面值赋给变量 或常数,或将其传递给需要字典的函数。
下面是如何创建 HTTP 响应代码及其相关消息的字典:
var responseMessages = [200: "OK", 403: "Access forbidden", 404: "File not found", 500: "Internal server error"]
推断 response seMessages 变量的类型为 [Int: String]。 字典的 Key 类型是 Int,而 字典是 String。
[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 会抱怨 Binary 操作符 = = 不能应用于两个 [String: Any]操作数。
[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:
Xcode 11• Swift 5.1
public func ==<K, L: Hashable, R: Hashable>(lhs: [K: L], rhs: [K: R] ) -> Bool { (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
let dic7: [String: String] = [ "key2": "200"] let dic8: [String: Date] = [ "key2": Date()] print(dic7 == dic8) // false
如果没有 Dictionary 的自定义类型,在 Swift 2 + 中,您可以使用 ==操作符来比较两个 Dictionary,以检查它们是否相等。
Dictionary
但是在某些情况下,如果使用自定义类型作为 Dictionary的值(如 struct) ,则必须采用 Equatable,以便该自定义类型使用 ==运算符。
struct
例如:
// 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") }
比较字典现在是本地的! (文档 给你)
Leo Dabus 已经写了一篇出色的文章,提出了公认的解决方案。然而,对我来说,我发现它还需要一个步骤才能完全可用。从他的代码中可以看出,您需要将字典类型设置为 [AnyHashable: Any],否则就会得到 Binary operator '==' cannot be applied to two '[String : Any]' operands,以便在我的示例中使用反序列化 JSON 中常用的字典。
[AnyHashable: Any]
Binary operator '==' cannot be applied to two '[String : Any]' operands
仿制药来救场了:
// Swift 3.0 func == <K, V>(left: [K:V], right: [K:V]) -> Bool { return NSDictionary(dictionary: left).isEqual(to: right) }
或者在另一个案例中,我有 [String: Any?]:
[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) }