在 Swift 中,flatMap 是一种用于处理集合、可选值以及其他嵌套数据结构的方法,主要作用是将嵌套的数据结构“展开”,并对每个元素应用变换操作。
flatMap 的作用和区别
与 map 类似,flatMap 对集合或可选值中的每个元素应用指定的变换。
与 map 不同的是,如果变换操作的结果是一个集合或可选值,flatMap 会将结果“扁平化”,从而消除一层嵌套。
适用场景
1、处理嵌套集合(例如二维数组)。
2、处理可选值嵌套。
3、展开和过滤某些数据类型。
flatMap 用于集合
1、处理嵌套集合
let nestedArray = [[1, 2, 3], [4, 5], [6]]
let flattenedArray = nestedArray.flatMap { $0 }
print(flattenedArray) // [1, 2, 3, 4, 5, 6]
这里 flatMap 将嵌套的二维数组“展平”成一维数组。
2、过滤并转换
let numbers = [1, 2, 3, 4, 5]
let evenNumbers = numbers.flatMap { $0 % 2 == 0 ? [$0] : [] }
print(evenNumbers) // [2, 4]
通过返回一个数组的方式,flatMap 可以同时实现过滤和转换。
flatMap 用于可选值
1、处理嵌套的可选值
let optionalValues: [Int?] = [1, nil, 3, nil, 5]
let flattenedValues = optionalValues.flatMap { $0 }
print(flattenedValues) // [1, 3, 5]
这里 flatMap 自动移除了 nil 值。
注意:在 Swift 4.1 中,compactMap 替代了 flatMap 处理可选值的功能,结果完全相同。
可能会存在如下报错:
'flatMap' is deprecated: Please use compactMap(_:) for the case where closure returns an optional value
Use 'compactMap(_:)' instead
这表示处理可选值的功能应该使用compactMap进行替代。
等价的写法:
let flattenedValues = optionalValues.compactMap { $0 }
flatMap 用于字符串处理
当有一组字符串并希望将其分解为单个字符数组时,可以使用 flatMap。
let words = ["Hello", "World"]
let characters = words.flatMap { $0 }
print(characters) // ["H", "e", "l", "l", "o", "W", "o", "r", "l", "d"]
这里 flatMap 将每个字符串分解为字符数组,然后将所有的字符数组“展平”成一个数组。
flatMap 和 map 的区别
1、带嵌套集合
let nestedArray = [[1, 2, 3], [4, 5], [6]]
let mappedArray = nestedArray.map { $0 }
print(mappedArray) // [[1, 2, 3], [4, 5], [6]]
let flattenedArray = nestedArray.flatMap { $0 }
print(flattenedArray) // [1, 2, 3, 4, 5, 6]
map 保留嵌套结构,flatMap 会“展开”嵌套结构。
2、处理可选值
let numbers = [1, 2, nil, 4]
let mappedNumbers = numbers.map { $0 }
print(mappedNumbers) // [Optional(1), Optional(2), nil, Optional(4)]
let flattenedNumbers = numbers.flatMap { $0 }
print(flattenedNumbers) // [1, 2, 4]
map 保留了 Optional 的结构,compactMap(或者 flatMap 在 Swift 4.0 中)移除了 nil。
flatMap 结合自定义类型
如果有自定义的容器类型,也可以实现 flatMap 的行为。
struct Box<T> {
let value: T
func flatMap<U>(_ transform: (T) -> Box<U>) -> Box<U> {
return transform(value)
}
}
let box = Box(value: 42)
let newBox = box.flatMap { Box(value: $0 * 2) }
print(newBox.value) // 84
这里 flatMap 将 Box 的值应用变换,并返回一个新的 Box。
总结
flatMap 的主要作用是消除嵌套层级。
用于集合时:将嵌套的集合“展平”。
用于可选值时:移除 nil。
从 Swift 4.1 开始,compactMap 更适用于可选值的处理,flatMap 更适用于集合或自定义类型。
相关文章
Swift高阶函数compactMap:https://fangjunyu.com/2024/12/21/swift%e9%ab%98%e9%98%b6%e5%87%bd%e6%95%b0compactmap/