簡體   English   中英

如何比較 Swift 中的兩個字典?

[英]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

斯威夫特 4 更新:

比較字典現在是原生的! (文檔在這里


斯威夫特 3:

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 中,當KeyValue都是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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM