如何在 Swift 中比较两个字典? [英] How do I compare two dictionaries in Swift?

查看:41
本文介绍了如何在 Swift 中比较两个字典?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

通过比较两个字典,我的意思是检查它们是否具有完全相同的键,并且对于每个键它们具有相同的值.

解决方案

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

let dic1: [String: AnyObject] = ["key1": 100, "key2": 200]让 dic2: [String: AnyObject] = ["key1": 100, "key2": 200]让 dic3: [String: AnyObject] = ["key1": 100, "key2": 250]println( NSDictionary(dictionary: dic1).isEqualToDictionary(dic2) )//trueprintln( NSDictionary(dictionary: dic1).isEqualToDictionary(dic3) )//false

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

public func ==(lhs: [String: AnyObject], rhs: [String: AnyObject] ) ->布尔{返回 NSDictionary(dictionary: lhs).isEqualToDictionary(rhs)}println(dic1 == dic2)//真println(dic1 == dic3)//假

<小时>

Xcode 9 • Swift 4

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

struct Dictionary: 集合,ExpressibleByDictionaryLiteral

<块引用>

说明

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

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

var responseMessages = [200: "OK",403:禁止访问",404:找不到文件",500内部服务器错误"]

<块引用>

responseMessages 变量被推断为具有 [Int: String] 类型.字典的Key类型是Int,而字典的Value类型是字典是String.

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

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

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

<小时>

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

来自文档:

static func ==(lhs: [Key : Value], rhs: [Key : Value]) ->布尔值

<小时>

测试:

let dic1 = ["key1": 100, "key2": 200]让 dic2 = ["key1": 100, "key2": 200]让 dic3 = ["key1": 100, "key2": 250]打印(dic1 == dic2)//真打印(dic1 == dic3)//假

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

let dic4: [String: Any] = ["key1": 100, "key2": "200"]让 dic5: [String: Any] = ["key1": 100, "key2": "200"]让 dic6: [String: Any] = ["key1": 100, "key2": Date()]print(dic4 == dic5)//二元运算符 == 不能应用于两个 `[String: Any]` 操作数

但是我们可以扩展 == 操作符功能,实现一个中缀操作符,将 Swift Dictionary 转换为 NSDictionary 并将字典值限制为 Hashable 协议:

<小时>

Xcode 11 • Swift 5.1

public func ==(lhs: [K: L], rhs: [K: R] ) ->布尔{(lhs 作为 NSDictionary).isEqual(to: rhs)}

<小时>

测试:

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

<小时>

print(dic4 == dic5)//真打印(dic4 == dic6)//假

<小时>

let dic7: [String: String] = [ "key2": "200"]让 dic8: [String: Date] = [ "key2": Date()]打印(dic7 == dic8)//假

Is there an easy way to compare two [String: AnyObject] dictionaries in swift, since it doesn't accept the == operator?

By comparing two dictionaries, I mean checking that they have the same exact keys and for every key they have the same values.

解决方案

As already mentioned by Hot Licks you can use NSDictionary method isEqualToDictionary() to check if they are equal as follow:

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

you can also implement a custom operator "==" as follow:

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

From the docs, dictionary is now defined as a struct:

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

Description

A collection whose elements are key-value pairs. A dictionary is a type of hash table, providing fast access to the entries it contains. Each entry in the table is identified using its key, which is a hashable type such as a string or number. You use that key to retrieve the corresponding value, which can be any object. In other languages, similar data types are known as hashes or associated arrays. Create a new dictionary by using a dictionary literal. A dictionary literal is a comma-separated list of key-value pairs, in which a colon separates each key from its associated value, surrounded by square brackets. You can assign a dictionary literal to a variable or constant or pass it to a function that expects a dictionary.

Here’s how you would create a dictionary of HTTP response codes and their related messages:

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

The responseMessages variable is inferred to have type [Int: String]. The Key type of the dictionary is Int, and the Value type of the dictionary is String.

To create a dictionary with no key-value pairs, use an empty dictionary literal ([:]).

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

Any type that conforms to the Hashable protocol can be used as a dictionary’s Key type, including all of Swift’s basic types. You can use your own custom types as dictionary keys by making them conform to the Hashable protocol.


We don't need to define a custom operator anymore:

From the docs:

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

In the example above all dictionary keys and values are the same type. If we try to compare two dictionaries of type [String: Any] Xcode will complain that Binary operator == cannot be applied to two [String: Any] operands.

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

But we can extend the == operator functionality implementing an infix operator, casting Swift Dictionary to NSDictionary and constraining the dictionary values to 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)
}


Testing:

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

这篇关于如何在 Swift 中比较两个字典?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆