理论
在 Swift 中,高阶函数是指那些能够接受一个或多个函数作为参数,或者返回一个函数作为结果的函数。Swift 标准库中提供了一些常见的高阶函数,比如 map、filter、reduce 等。它们通常用于操作集合类型(如数组、字典等),使代码更加简洁和表达力强。
1. map 函数
map 用于将集合中的每个元素转换成新的元素,返回一个新的集合。
let numbers = [1, 2, 3, 4, 5]
let squaredNumbers = numbers.map { $0 * $0 }
print(squaredNumbers) // 输出: [1, 4, 9, 16, 25]
2. filter 函数
filter 用于筛选出符合条件的元素,返回一个新的数组。
let numbers = [1, 2, 3, 4, 5, 6]
let evenNumbers = numbers.filter { $0 % 2 == 0 }
print(evenNumbers) // 输出: [2, 4, 6]
3. reduce 函数
reduce 用于将集合中的元素结合成一个单一的值。它需要一个初始值和一个闭包,闭包会依次将元素合并到一个结果中。
let numbers = [1, 2, 3, 4, 5]
let sum = numbers.reduce(0) { $0 + $1 }
print(sum) // 输出: 15
4. flatMap
flatMap 用于将一个集合中的多个元素展开成一个新的集合。常用于处理数组嵌套的情况。
let arrayOfArrays = [[1, 2], [3, 4], [5, 6]]
let flattenedArray = arrayOfArrays.flatMap { $0 }
print(flattenedArray) // 输出: [1, 2, 3, 4, 5, 6]
5. compactMap 函数
compactMap 类似于 map,但是它会自动过滤掉 nil 值,返回一个非 nil 的新数组。
let strings = ["1", "2", "three", "4"]
let numbers = strings.compactMap { Int($0) }
print(numbers) // 输出: [1, 2, 4]
6. sort 函数
sort 是原地排序函数,修改原数组。
var numbers = [5, 2, 4, 1, 3]
let sortedNumbers = numbers.sorted()
print(sortedNumbers) // 输出: [1, 2, 3, 4, 5]
7. sorted 函数
sorted 会返回一个新的排序后的数组,不修改原数组。
var numbers = [5, 2, 4, 1, 3]
let sortedNumbers = numbers.sorted()
print(sortedNumbers) // 输出: [1, 2, 3, 4, 5]
let names = ["Zoe", "Alice"]
let sortedNames = names.sorted { $0 < $1 } // ["Alice", "Zoe"]
// 简写:
let sortedNames = names.sorted(by: <)
8. forEach 函数
forEach 用于对集合中的每个元素执行某个操作。
let numbers = [1, 2, 3, 4, 5]
numbers.forEach { print($0) }
9. 组合使用
链式调用提高可读性:
let result = numbers
.filter { $0 % 2 == 0 } // 筛选偶数
.map { $0 * 3 } // 每个元素乘3
.reduce(0, +) // 求和
// 若 numbers = [1, 2, 3, 4],结果为 (2+4)*3 = 18
10. 惰性求值 (lazy)
优化性能,避免中间数组生成:
let result = numbers.lazy
.filter { $0 % 2 == 0 }
.map { $0 * 3 }
// 实际计算延迟到访问元素时进行
11. 自定义高阶函数
接受闭包作为参数的函数:
func retry(times: Int, task: () -> Bool) {
for _ in 0..<times {
if task() { return }
}
}
retry(times: 3) {
print("执行任务...")
return arc4random_uniform(3) == 0 // 模拟随机成功
}
注意事项:
1.性能:链式调用可能生成中间数组,对大数据集考虑使用 lazy。
2.闭包捕获:注意循环引用,使用 [weak self] 或 [unowned]。
3.类型匹配:如 reduce 的初始值需与结果类型一致。