假設在咱們開發一個商品頁面的時候,需求是按商品的分類來分 section,但後臺給咱們返回的數據是整個列表的商品數組。在 Swift 5 以前,咱們只能經過遍歷數組來分組:數組
struct Shop {
let name: String
let category: String
}
let shops = [Shop(name: "iPhone 11", category: "phone"),
Shop(name: "iPhone XR", category: "phone"),
Shop(name: "Redmi note8", category: "phone"),
Shop(name: "衛龍", category: "food"),
Shop(name: "老乾媽", category: "food")]
let allCategory = Set(shops.map { $0.category })
var shopSections = [String: [Shop]]()
allCategory.forEach { (cate) in
let cateShops = shops.filter { $0.category == cate }
shopSections[cate] = cateShops
}
複製代碼
在 Swift 5.0 發佈之後,Dictionary 新添加了一個初始化方法:init(grouping:by:)
。該方法能夠經過閉包中返回的 key 將數組組織爲一個字典。用該方法重寫上面的代碼:bash
let shopSections = Dictionary(grouping: shops) { (shop) -> String in
return shop.category
}
複製代碼
上面的代碼能夠經過 Swift 的語法糖更加精簡:閉包
let shopSections = Dictionary(grouping: shops) { $0.category }
複製代碼
由於該方法提供了一個閉包來給咱們操做,因此咱們不單單能夠返回當前模型的字段,咱們還能夠根據需求來靈活變通。好比上面的例子中,假如咱們的需求變動爲按商品的歸屬地來進行分類。雖而後臺返回的字段沒有返回,但咱們依然能夠經過商品來進行判斷:app
let shopSections = Dictionary(grouping: shops) { (shop) -> String in
if shop.name.contains("iPhone") {
return "US"
}
return "China"
}
print(shopSections)
/*
["US": [DataStructureDemo.Shop(name: "iPhone 11", category: "phone"), DataStructureDemo.Shop(name: "iPhone XR", category: "phone")],
"China": [DataStructureDemo.Shop(name: "Redmi note8", category: "phone"), DataStructureDemo.Shop(name: "衛龍", category: "food"),
DataStructureDemo.Shop(name: "薯條", category: "food")]]
*/
複製代碼
你們都知道只要遵照 Hashable 的數據類型均可以當作字典的 key,好比 Int、String等。因此,咱們也可讓結構體來當作字典的 key,只要它遵照了該協議:ui
struct Company: Hashable {
let name: String
}
struct Shop {
let name: String
let category: String
let company: Company
}
let apple = Company(name: "蘋果")
let littleMi = Company(name: "小米")
let wl = Company(name: "衛龍")
let lgm = Company(name: "老乾媽")
let shops = [Shop(name: "iPhone 11", category: "phone", company: apple),
Shop(name: "iPhone XR", category: "phone", company: apple),
Shop(name: "Redmi note8", category: "phone", company: littleMi),
Shop(name: "衛龍", category: "food", company: wl),
Shop(name: "薯條", category: "food", company: lgm)]
let shopSections = Dictionary(grouping: shops) { return $0.company }
print(shopSections)
/*
[DataStructureDemo.Company(name: "小米"): [DataStructureDemo.Shop(name: "Redmi note8", category: "phone", company: DataStructureDemo.Company(name: "小米"))], DataStructureDemo.Company(name: "蘋果"): [DataStructureDemo.Shop(name: "iPhone 11", category: "phone", company: DataStructureDemo.Company(name: "蘋果")), DataStructureDemo.Shop(name: "iPhone XR", category: "phone", company: DataStructureDemo.Company(name: "蘋果"))], DataStructureDemo.Company(name: "衛龍"): [DataStructureDemo.Shop(name: "衛龍", category: "food", company: DataStructureDemo.Company(name: "衛龍"))], DataStructureDemo.Company(name: "老乾媽"): [DataStructureDemo.Shop(name: "薯條", category: "food", company: DataStructureDemo.Company(name: "老乾媽"))]]
*/
複製代碼
但願本文能讓你清晰的知道該如何使用 init(grouping:by:)
,能給你帶來更高的開發效率。😄spa