??
在 Swift 中崔步,高階函數(shù)是非常常見且實(shí)用的概念菲茬,它可以讓我們以更簡(jiǎn)單铺呵、更表達(dá)式化的方式來處理集合類型裹驰。
常見的高階函數(shù)
1、map
: 將集合中的每一個(gè)元素通過映射轉(zhuǎn)換為另外一個(gè)類型片挂。
struct Person{
var name: String
var age: Int
var hobbies:[String]
}
let array = [Person(name: "張三", age: 30, hobbies: ["吃"]),
Person(name: "李四", age: 10, hobbies: ["合"]),
Person(name: "王五", age: 40, hobbies: [])]
// 普通遍歷
var result = [String]()
for p in array {
result.append(p.name)
}
SPPrint.print(result) //["張三", "李四", "王五"]
// 使用map函數(shù)可以將上述代碼簡(jiǎn)化:
let result1 = array.map{ $0.name }
SPPrint.print(result1) //["張三", "李四", "王五"]
2幻林、flatMap
: 類似于 map,不過它對(duì)于返回類型為可選值的映射會(huì)將結(jié)果展開到最終結(jié)果中并且同時(shí)丟棄 nil 值音念。
let allHobbies = array.flatMap { $0.hobbies }
SPPrint.print(allHobbies) // ["吃", "合"]
3沪饺、reduce
: 將集合中的元素累積成一個(gè)值,也可以初始化一個(gè)初始值并和集合中的元素進(jìn)行累積操作闷愤。
//函數(shù)用于對(duì)一個(gè)集合中的元素進(jìn)行累加或者其他操作整葡,返回一個(gè)計(jì)算結(jié)果
let ages = array.reduce(0) { $0 + $1.age}
SPPrint.print(ages) // 80
let numbers = [1, 2, 3, 4]
let sum = numbers.reduce(0, +)
SPPrint.print(sum) // 10
4、sorted
: 對(duì)集合中的元素進(jìn)行排序讥脐,可以指定排序規(guī)則遭居。
let numbers = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]
let sortedNumbers = numbers.sorted()
SPPrint.print(sortedNumbers) // [1, 1, 2, 3, 3, 4, 5, 5, 5, 6, 9]
let descendingNumbers = numbers.sorted(by: >)
SPPrint.print(descendingNumbers) // [9, 6, 5, 5, 5, 4, 3, 3, 2, 1, 1]
var students = ["Kofi", "Abena", "Peter", "Kweku", "Akosua"]
students.sort(by: >)
SPPrint.print(students) //["Peter", "Kweku", "Kofi", "Akosua", "Abena"]
5、forEach
: 對(duì)集合中的每一個(gè)元素執(zhí)行操作旬渠,但不返回任何值俱萍。
let numbers = [1, 2, 3, 4]
numbers.forEach { SPPrint.print($0) }
// 1
// 2
// 3
// 4
6、compactMap
: 對(duì)集合中的元素進(jìn)行映射操作告丢,并把返回值不為 nil 的元素重新組成一個(gè)新的集合枪蘑。
let strs = ["1", "2", "3", "hello", "4"]
let nums = strs.compactMap { Int($0) }
SPPrint.print(nums) // [1, 2, 3, 4]
let evenNumbers = strs.compactMap { Int($0) }.filter { $0 % 2 == 0 }
SPPrint.print(evenNumbers) //[2, 4]
7、contains
: 判斷集合中是否包含某個(gè)元素岖免。
let numbers = [1, 2, 3, 4]
let containsThree = numbers.contains(3)
print(containsThree) // true
8岳颇、first(where:)
: 查找滿足特定條件的第一個(gè)元素,并返回該元素觅捆。
//開發(fā)中常見場(chǎng)景:查找數(shù)組中滿足某些條件的第一個(gè)元素
if let person = array.first(where: { $0.name == "王五"}) {
SPPrint.print("\(person.name)") //王五
}else {
SPPrint.print("not found")
}
9赦役、filter
: 該方法可以根據(jù)一個(gè)閉包中的條件篩選出需要保留的元素,并返回一個(gè)符合條件的新數(shù)組栅炒〉嗨ぃ可以通過使用這個(gè)新數(shù)組來替換原始數(shù)組。
//使用了filter()方法赢赊,并將一個(gè)閉包作為參數(shù)傳遞給它乙漓。
//在這個(gè)閉包中,檢查每個(gè)元素的名字是否不等于“Bob”释移,如果匹配成功叭披,則返回true,表示這個(gè)元素應(yīng)該被保留玩讳。
//最后涩蜘,我們用符合條件的新數(shù)組替換原始數(shù)組嚼贡。
array = array.filter { $0.name != "王五" }
SPPrint.print(array)
//[SwiftProject.Person(name: "張三", age: 30, hobbies: ["吃"]), SwiftProject.Person(name: "李四", age: 10, hobbies: ["合"])]
10、removeAll
: 該方法可以根據(jù)一個(gè)閉包中的條件篩選出需要被移除的元素
//使用了removeAll()方法同诫,并將一個(gè)符合特定條件的閉包作為參數(shù)傳遞給它粤策。
//在這個(gè)閉包中,我們檢查每個(gè)元素的名字是否為“Bob”误窖,如果匹配成功叮盘,則返回true,表示這個(gè)元素應(yīng)該被移除霹俺。
array.removeAll { $0.name == "王五" }
SPPrint.print(array)
// [SwiftProject.Person(name: "張三", age: 30, hobbies: ["吃"]), SwiftProject.Person(name: "李四", age: 10, hobbies: ["合"])]
11柔吼、allSatisfy
: 判斷集合中的所有元素是否都滿足某個(gè)條件。
let numberss = [1, 2, 3, 4]
let allGreaterThanZero = numberss.allSatisfy { $0 > 0 }
let allGreaterThanOne = numberss.allSatisfy { $0 > 1 }
SPPrint.print(allGreaterThanZero) // true
SPPrint.print(allGreaterThanOne) // false
12丙唧、joined
: 將多個(gè)集合拼接成一個(gè)大集合愈魏,如果是二維及以上的集合會(huì)自動(dòng)進(jìn)行降維處理。
let numberss = [1, 2, 3, 4]
let allGreaterThanZero = numberss.allSatisfy { $0 > 0 }
let allGreaterThanOne = numberss.allSatisfy { $0 > 1 }
SPPrint.print(allGreaterThanZero) // true
SPPrint.print(allGreaterThanOne) // false
13艇棕、firstIndex(where:)
: 用于查找集合中第一個(gè)滿足某個(gè)條件的元素的索引蝌戒。
let numbersssss = [1, 2, 3, 4]
let firstEvenIndex = numbersssss.firstIn
dex(where: { $0 % 2 == 0 })
SPPrint.print(firstEvenIndex ?? 0) // 1
let index = array.firstIndex(where: { $0.name == "王五"})
SPPrint.print(index) // 2
14、zip
: 將兩個(gè)集合中的元素一一對(duì)應(yīng)起來沼琉,組成一個(gè)新的元組數(shù)組北苟。
let numbs = [1, 2, 3]
let letters = ["A", "B", "C"]
let pairs = zip(numbs, letters)
SPPrint.print(Array(pairs)) //[(1, "A"), (2, "B"), (3, "C")]
15、partition(by:)
: 將集合劃分成兩個(gè)部分打瘪,使得滿足某個(gè)條件的元素放在前面友鼻,不滿足條件的放在后面,并返回分界點(diǎn)索引闺骚。
// 將數(shù)組分成兩部分彩扔,滿足條件的元素在左側(cè),不滿足條件的元素在右側(cè)僻爽。
// 然后虫碉,只需要遍歷左側(cè)部分的元素,就可以獲得所有滿足條件的元素胸梆。
var passengers = ["Alice", "Bob", "Charlie", "David","b"]
SPPrint.print(passengers.partition { $0.count <= 4 })
// ["Alice", "David", "Charlie", "Bob", "b"]
16敦捧、stride
: 用于創(chuàng)建一個(gè)由指定范圍內(nèi)元素組成的序列
//使用 stride 函數(shù)創(chuàng)建了一個(gè)由 0 到 10 的整數(shù)(不包括 10)組成的序列,步長(zhǎng)為 2碰镜。
for i in stride(from: 0, to: 10, by: 2) {
SPPrint.print(i) //打印的結(jié)果是 0兢卵、2、4绪颖、6秽荤、8
}
//使用 stride 函數(shù)創(chuàng)建了一個(gè)從 10 到 1 的整數(shù)序列,步長(zhǎng)為 -1。因此
for i in stride(from: 10, to: 0, by: -1) {
SPPrint.print(i) //打印的結(jié)果是 10窃款、9课兄、8、...雁乡、2第喳、1
}