Swift 4.0 中對 Dictionary 的改進(轉載)

Swift 4 發佈已經有一段時間了,不知道你們有沒有切換到 4.0 版本。 此次 4.0 更新給我最大的感覺就是沒有了前幾回升級的跳躍式變化。 不用爲了更新語言版本,徹底推翻已有的項目,這也是 Swift 慢慢趨向於穩定的標誌。swift

我們此次說說 Swift 4.0 對 Dictionary 這個常常會用到的類的改進。數組

自動根據 key 分組

Dictionary 新增了一個構造方法,能夠將給定的一個數組,根據指定的條件進行分組。 來看一個例子:閉包

struct Person {

    var name: String
    var gender: Gender
    var age: Int

    enum Gender {
        case male
        case female
    }

}
複製代碼

這裏有一個 Person 結構, 而後咱們初始化一個數組:app

let p1 = Person(name: "aa", gender: .female, age: 22)
let p2 = Person(name: "bb", gender: .male, age: 24)
let p3 = Person(name: "cc", gender: .male, age: 21)

let persons = [p1, p2, p3]
複製代碼

如今用新的 Dictionary 構造方法,能夠當即將這組 Person 實例根據他們的 gender 屬性進行分組:工具

let groupedDict = Dictionary(grouping: persons) { p in

    return p.gender

}
複製代碼

這個構造方法,第一個參數 grouping 接收的是 persons 數組, 第二個參數是一個閉包,用於返回根據進行分組的依據,咱們這裏返回的是 p.gender。結果一目瞭然:post

[
    .male: [
        Person(name: "bb", gender: .male, age: 24), 
        Person(name: "cc", gender: .male, age: 21)
    ], 
    .female: [
        Person(name: "aa", gender: .female, age: 22)
    ]
]
複製代碼

以往要實現這樣的功能,就須要手動遍歷整個數組,取出 key, 而後生成字典, 如今方便不少。ui

value 無縫轉換

另一個比較有用的特性是,Dictionary 提供的 mapValues 方法。 還以咱們剛纔生成的 groupedDict 爲例,能夠進行這樣的操做:spa

let count = groupedDict.mapValues { persons in
    persons.count
}
複製代碼

先看一下輸出,你們可能就猜到這個方法的用途是什麼了:code

[
    .male: 2, 
    .female: 1
]
複製代碼

上面的輸出能夠看到, mapValues 會遍歷每個 key 對應的 values, 而後傳遞給閉包進行自定義轉換。 咱們例子中的閉包返回的就是每一個 key 對應的 Person 集合的數量,最生成了一個新的 Dictionary,裏面的 key 和以前同樣,只是對應的值變成了咱們閉包中自定義的了。blog

mapValues 方法一樣是一個幫助咱們解決繁雜操做的工具方法。

從鍵值對元組中直接構建

假如咱們有這樣一個數組:

let personsTuples = [("group 1", [p1, p2]),  ("group 2", [p3])]
複製代碼

而後能夠調用 uniqueKeysWithValues 構造方法直接初始化字典:

let dict = Dictionary(uniqueKeysWithValues: personsTuples)
複製代碼

personsTuples 數組中,每個元素都是一個元組(Tuple), 這個構造方法把元組中的第一項當作 key, 第二項當作 value, 生成一個新的 Dictionary,以下所示:

[
    "group 1": [
        Person(name: "aa", gender: .female, age: 22), 
        Person(name: "bb", gender: .male, age: 24)
    ], 
    "group 2": [
        Person(name: "cc", gender: .male, age: 21)
    ]
]
複製代碼

使用 uniqueKeysWithValues 構造方法時候須要注意,就是傳入的數組中,不能有重複的 key, 不然會報運行時錯誤,好比這個數組就會報錯:

let personsTuples = [("group 1", [p1, p2]),  ("group 2", [p3]), ("group 2", [p4])]
複製代碼

上面數組中 group 2 出現了兩次。 若是用它來初始化的話,就會出錯。 因此 Swift 4.0 還提供了另一個初始化方法, 對於上面這個數組,能夠調用:

let dict = Dictionary(personsTuples) { old, new in
    return new
}
複製代碼

第二個閉包參數,會在遇到重複的 key 時候調用。 它提供兩個參數,一個是一樣這個 key 的上一個值 old, 還有當前的值 new。 咱們這裏直接返回 new,意思就是 每次遇到重複的 key, 就用新的值代替老的值。 這樣初始化後,生成的 Dictionary 結構以下:

[
    "group 1": [
            p1,
            p2
    ], 
    "group 2": [
            p4
    ]
]
複製代碼

group 2 中的值, 是第二次 key 所對應的 p4。

提供默認值

若是咱們訪問了一個字典中不存在的 key, 會返回 nil:

dict["group 3"]
複製代碼

由於上面字典中,不存在 group 3 這個 key, 因此它返回了 nil。 Swift 4 中新增了指定默認值的能力:

dict["group 3", default: []]
複製代碼

這樣調用,若是 group 3 這個 key 不存在的話, 就會返回咱們指定的默認值空數組, 而不是 nil 了。 這個特性在咱們處理 JSON 數據解析這類的問題上很實用。

過濾器

過濾器對於集合類來講是比較經常使用的功能。 Swift 4 中對 Dictionary 類型也提供了過濾器的支持:

let filteredDict = dict.filter { key, val in

    return val.count >= 2

}
複製代碼

filter 方法接收一個閉包,它會遍歷 Dictionary 中全部的元素,而且做爲閉包的參數傳入。 咱們須要經過閉包的返回值肯定這個元素是否被保留。 上面的例子中,好比咱們 dict 中的元素是 :

[
    "group 1": [
            p1,
            p2
    ], 
    "group 2": [
            p4
    ]
]
複製代碼

調用 filter 後,咱們只保留數量大於 2 的集合:

[
    "group 1": [
            p1,
            p2
    ]
]
複製代碼

總結

以上就是 Swift 4.0 對於 Dictionary 的主要改進。 這些新增的工具方法對於提升咱們開發效率和代碼質量都有幫助,但願這裏的介紹對你有幫助。 關於 Dictionary 更完整的信息,你們還能夠參考蘋果官方的文檔,還有 Swift Blog 中的介紹。

參考文獻

Dictionary 官方文檔:https://developer.apple.com/documentation/swift/dictionary

Swift Blog: https://swift.org/blog/dictionary-and-set-improvements/

轉載自:http://swiftcafe.io/post/swift4-dict

相關文章
相關標籤/搜索