Swift 4 發佈已經有一段時間了,不知道你們有沒有切換到 4.0 版本。 此次 4.0 更新給我最大的感覺就是沒有了前幾回升級的跳躍式變化。 不用爲了更新語言版本,徹底推翻已有的項目,這也是 Swift 慢慢趨向於穩定的標誌。swift
我們此次說說 Swift 4.0 對 Dictionary 這個常常會用到的類的改進。數組
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
另一個比較有用的特性是,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