深入淺出的聊聊Swift高階函數(shù)
初探高階函數(shù)
在 Swift 中,高階函數(shù)一共有下面幾個:
- map:對給定數(shù)組每個元素,執(zhí)行閉包中的映射,將映射結(jié)果放置在數(shù)組中返回。
- flatMap:對給定數(shù)組的每個元素,執(zhí)行閉包中的映射,對映射結(jié)果進(jìn)行合并操作,然后將合并操作后的結(jié)果放置在數(shù)組中返回。
- compactMap:對給定數(shù)組的每個元素,執(zhí)行閉包中的映射,將非空的映射結(jié)果放置在數(shù)組中返回。
- compactMap對給定數(shù)組的每個元素,執(zhí)行閉包中的映射,將非空的映射結(jié)果-鍵值對放置在字典中返回。
- filter:對給定數(shù)組的每個元素,執(zhí)行閉包中的操作,將符合條件的元素放在數(shù)組中返回。
- reduce:對給定數(shù)組的每個元素,執(zhí)行閉包中的操作對元素進(jìn)行合并,并將合并結(jié)果返回。
通過上面的闡述,我們大概了解到了這幾個函數(shù)是做什么用的,下面我們在通過幾個例子來具體看一下代碼上如何使用。
map
對于 map 函數(shù),使用場景就是將數(shù)組的類型映射為別的類型。比如,我們有一個模型數(shù)組,模型的 id 字段我們從服務(wù)器拿的是 String 類型,在某種場景下我們需要轉(zhuǎn)為 Int 類型,這時候我們就可以通過 map 函數(shù)來實現(xiàn)該需求。
struct Student {
let id: String
let name: String
let age: Int
}
let stu1 = Student(id: "1001", name: "stu1", age: 12)
let stu2 = Student(id: "1002", name: "stu2", age: 14)
let stu3 = Student(id: "1003", name: "stu3", age: 16)
let stu4 = Student(id: "1004", name: "stu4", age: 20)
let stus = [stu1, stu2, stu3, stu4]
let intIds = stus.map { (stu) in
Int(stu.id)
}
print(intIds) //[Optional(1001), Optional(1002), Optional(1003), Optional(1004)]
通過上述代碼,我們將 id 字段從 String 映射為了 Int? 類型,這并不是我們想要的 Int 類型。如果我們需要訪問元素的話還得需要解包,那么我們?nèi)绾渭饶軐⒃赜成溆帜茏詣雍Y選 nil 的值呢?這時,就輪到 compactmap 出馬了。
compactMap
我們將上面的代碼替換為:
let intIds = stus.compactMap { (stu) in
Int(stu.id)
}
這時,我們再打印 intIds 就會發(fā)現(xiàn)它已經(jīng)為 Int 類型了。
compactMapValues
對于 Set 和 Array ,你可以使用 compactMap 來獲得非空的集合,但是對于 Dictionary 來說,這個函數(shù)是不起作用的。
let dict = ["key1": 10, "key2": nil]
let result = dict.compactMap { $0 }
print(result) //[(key: "key1", value: Optional(10)), (key: "key2", value: nil)]
這時候,我們需要使用 compactMapValues 函數(shù)來獲得非空的字典。
print(result) //["key1": 10]
let result = dict.compactMapValues { $0 }
print(result) //["key1": 10]
flatMap
對于 flatMap,主要的應(yīng)用場景就是你想獲得一個單層集合的數(shù)組。通過下面的代碼來看一下 map 和 flapMap 的區(qū)別。
let scoresByName = ["Henk": [0, 5, 8], "John": [2, 5, 8]]
let mapped = scoresByName.map { $0.value }
// [[2, 5, 8], [0, 5, 8]]
print(mapped)
let flatMapped = scoresByName.flatMap { $0.value }
// [2, 5, 8, 0, 5, 8]
map 會直接將元素放在數(shù)組中,而 flatMap 會將元素平鋪在一個數(shù)組中。實際上,s.flatMap(transform) 等同于s.map(transform).joined()。
filter
這個函數(shù)就如同單詞的意思:查找。將符合條件的元素查找出來放置在數(shù)組中返回。比如我們想查找年齡大于18歲的所有學(xué)生。
let adults = stus.filter { (stu) -> Bool in
stu.age >= 18
}
print(adults) // 數(shù)組中只包含stu4 學(xué)生
reduce
對于 reduce,我們的使用場景就是對數(shù)組中的元素進(jìn)行組合運算,比如我們想計算所有學(xué)生的年齡加載一起是多少。
let totalAges = stus.reduce(0) { (result, stu) in
return result + stu.age
}
print(totalAges) // 62
該函數(shù)的第一個參數(shù)為初始值,后面元組中的第一個參數(shù)為每次計算的結(jié)果,第二個參數(shù)為每次遍歷的元素。最后將計算的結(jié)果返回。
組合使用
對于使用高階函數(shù)最大的好處就是可以進(jìn)行函數(shù)式編程了。下面我們通過幾個小栗子來對這幾個高階函數(shù)進(jìn)行組合使用。
將 String 類型映射為 Int 類型,并查找id大于1002的所有學(xué)生
let adults = stus.compactMap { (stu) in
Int(stu.id)
}.filter { (id) -> Bool in
id > 1002
}
print(adults) //[1003, 1004]
計算年齡大于12的所有學(xué)生年齡總和
let totalAge = stus.filter { (stu) -> Bool in
stu.age > 12
}.reduce(0) { (result, stu) in
return result + stu.age
}
print(totalAge) // 50
總結(jié)
到此這篇關(guān)于Swift高階函數(shù)的文章就介紹到這了,更多相關(guān)Swift高階函數(shù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Swift實現(xiàn)監(jiān)聽鍵盤通知及一些處理詳解
這篇文章主要給大家介紹了關(guān)于Swift實現(xiàn)監(jiān)聽鍵盤通知及一些處理的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2018-01-01
利用swift實現(xiàn)卡片橫向滑動動畫效果的方法示例
卡片橫向滑動動畫效果相信對大家來說都不陌生,下面這篇文章主要給大家介紹了關(guān)于利用swift實現(xiàn)卡片橫向滑動動畫效果的方法示例,文中通過示例代碼介紹的非常詳細(xì),對大家具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起看看吧。2017-07-07
Swift之for循環(huán)的基礎(chǔ)使用學(xué)習(xí)
這篇文章主要為大家介紹了Swift之for循環(huán)的基礎(chǔ)學(xué)習(xí),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-06-06

