在 Swift 中,高阶函数是非常常见且实用的概念,它可以让我们以更简单、更表达式化的方式来处理集合类型。
常见的高阶函数
1、map
: 将集合中的每一个元素通过映射转换为另外一个类型。
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函数可以将上述代码简化:
let result1 = array.map{ $0.name }
SPPrint.print(result1) //["张三", "李四", "王五"]
2、flatMap
: 类似于 map,不过它对于返回类型为可选值的映射会将结果展开到最终结果中并且同时丢弃 nil 值。
let allHobbies = array.flatMap { $0.hobbies }
SPPrint.print(allHobbies) // ["吃", "合"]
3、reduce
: 将集合中的元素累积成一个值,也可以初始化一个初始值并和集合中的元素进行累积操作。
//函数用于对一个集合中的元素进行累加或者其他操作,返回一个计算结果
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
: 对集合中的元素进行排序,可以指定排序规则。
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
: 对集合中的每一个元素执行操作,但不返回任何值。
let numbers = [1, 2, 3, 4]
numbers.forEach { SPPrint.print($0) }
// 1
// 2
// 3
// 4
6、compactMap
: 对集合中的元素进行映射操作,并把返回值不为 nil 的元素重新组成一个新的集合。
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
: 判断集合中是否包含某个元素。
let numbers = [1, 2, 3, 4]
let containsThree = numbers.contains(3)
print(containsThree) // true
8、first(where:)
: 查找满足特定条件的第一个元素,并返回该元素。
//开发中常见场景:查找数组中满足某些条件的第一个元素
if let person = array.first(where: { $0.name == "王五"}) {
SPPrint.print("\(person.name)") //王五
}else {
SPPrint.print("not found")
}
9、filter
: 该方法可以根据一个闭包中的条件筛选出需要保留的元素,并返回一个符合条件的新数组。可以通过使用这个新数组来替换原始数组。
//使用了filter()方法,并将一个闭包作为参数传递给它。
//在这个闭包中,检查每个元素的名字是否不等于“Bob”,如果匹配成功,则返回true,表示这个元素应该被保留。
//最后,我们用符合条件的新数组替换原始数组。
array = array.filter { $0.name != "王五" }
SPPrint.print(array)
//[SwiftProject.Person(name: "张三", age: 30, hobbies: ["吃"]), SwiftProject.Person(name: "李四", age: 10, hobbies: ["合"])]
10、removeAll
: 该方法可以根据一个闭包中的条件筛选出需要被移除的元素
//使用了removeAll()方法,并将一个符合特定条件的闭包作为参数传递给它。
//在这个闭包中,我们检查每个元素的名字是否为“Bob”,如果匹配成功,则返回true,表示这个元素应该被移除。
array.removeAll { $0.name == "王五" }
SPPrint.print(array)
// [SwiftProject.Person(name: "张三", age: 30, hobbies: ["吃"]), SwiftProject.Person(name: "李四", age: 10, hobbies: ["合"])]
11、allSatisfy
: 判断集合中的所有元素是否都满足某个条件。
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
: 将多个集合拼接成一个大集合,如果是二维及以上的集合会自动进行降维处理。
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:)
: 用于查找集合中第一个满足某个条件的元素的索引。
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
: 将两个集合中的元素一一对应起来,组成一个新的元组数组。
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:)
: 将集合划分成两个部分,使得满足某个条件的元素放在前面,不满足条件的放在后面,并返回分界点索引。
// 将数组分成两部分,满足条件的元素在左侧,不满足条件的元素在右侧。
// 然后,只需要遍历左侧部分的元素,就可以获得所有满足条件的元素。
var passengers = ["Alice", "Bob", "Charlie", "David","b"]
SPPrint.print(passengers.partition { $0.count <= 4 })
// ["Alice", "David", "Charlie", "Bob", "b"]
16、stride
: 用于创建一个由指定范围内元素组成的序列
//使用 stride 函数创建了一个由 0 到 10 的整数(不包括 10)组成的序列,步长为 2。
for i in stride(from: 0, to: 10, by: 2) {
SPPrint.print(i) //打印的结果是 0、2、4、6、8
}
//使用 stride 函数创建了一个从 10 到 1 的整数序列,步长为 -1。因此
for i in stride(from: 10, to: 0, by: -1) {
SPPrint.print(i) //打印的结果是 10、9、8、...、2、1
}