如何優雅的將數組元素映射到字典中(Swift)

之前

假設在咱們開發一個商品頁面的時候,需求是按商品的分類來分 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

相關文章
相關標籤/搜索