![](/img/trans.png)
[英]How do i compare two dictionaries in swift and then append any similarities to a new dictionary?
[英]How do I compare two dictionaries in Swift?
有没有一种简单的方法可以在 swift 中比较两个[String: AnyObject]
字典,因为它不接受==
运算符?
通过比较两个字典,我的意思是检查它们是否具有完全相同的键,并且对于每个键它们具有相同的值。
正如 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 • 斯威夫特 4
从文档中,字典现在被定义为一个结构:
struct Dictionary<Key : Hashable, Value> : Collection, ExpressibleByDictionaryLiteral
描述
元素为键值对的集合。 字典是一种哈希表,提供对其包含的条目的快速访问。 表中的每个条目都使用其键标识,键是可散列的类型,例如字符串或数字。 您可以使用该键来检索相应的值,该值可以是任何对象。 在其他语言中,类似的数据类型被称为散列或关联数组。 使用字典文字创建新字典。 字典文字是逗号分隔的键值对列表,其中冒号将每个键与其关联的值分开,并用方括号括起来。 您可以将字典文字分配给变量或常量,或将其传递给需要字典的函数。
以下是创建 HTTP 响应代码及其相关消息字典的方法:
var responseMessages = [200: "OK",
403: "Access forbidden",
404: "File not found",
500: "Internal server error"]
推断 responseMessages 变量的类型为
[Int: String]
。 字典的 Key 类型是Int
,字典的 Value 类型是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:
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
比较字典现在是原生的! (文档在这里)
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)
}
在 Swift 2 中,当Key
和Value
都是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)。
没有自定义类型的 Dictionary 值,在 Swift 2+ 中,您可以使用==
运算符来比较两个Dictionary
以检查它们是否相等。
但在某些情况下,自定义类型作为Dictionary
的值(如struct
),您必须采用Equatable
以便该自定义类型使用==
运算符。
前任:
// 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")
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.