在 Swift 中,compactMap 是一个强大的高阶函数,用于对集合中的元素进行映射,同时丢弃 nil 值,返回一个新的数组。
compactMap 的作用
对集合的每个元素应用一个转换(映射)。
如果转换结果为 nil,则丢弃该元素。
返回一个由非 nil 值组成的新数组。
与 map 的区别是,compactMap 自动过滤掉 nil 值,而 map 会保留 nil,如果结果包含 nil,就会得到一个数组的可选类型元素([T?])。
语法
let result = collection.compactMap { transform($0) }
collection 是操作的数组或其他集合。
transform 是一个闭包,将集合中的每个元素映射为一个新的值。
示例
1、转换并移除 nil 值
将字符串数组中的数字字符串转换为整数,同时移除无法转换的值:
let strings = ["1", "2", "three", "4"]
let numbers = strings.compactMap { Int($0) }
print(numbers) // [1, 2, 4]
2、扁平化嵌套数组
将嵌套数组中的所有值提取出来,同时忽略嵌套中的 nil:
let nestedArray: [[Int?]] = [[1, 2, nil], [nil, 3, 4], [5, nil]]
let flattened = nestedArray.flatMap { $0.compactMap { $0 } }
print(flattened) // [1, 2, 3, 4, 5]
3、操作复杂对象
处理自定义类型数组:
struct User {
let name: String
let age: Int?
}
let users = [
User(name: "Alice", age: 25),
User(name: "Bob", age: nil),
User(name: "Charlie", age: 30)
]
let ages = users.compactMap { $0.age }
print(ages) // [25, 30]
compactMap 和 map 的区别
使用 map
let strings = ["1", "2", "three", "4"]
let mappedNumbers = strings.map { Int($0) }
print(mappedNumbers) // [Optional(1), Optional(2), nil, Optional(4)]
使用 compactMap
let compactMappedNumbers = strings.compactMap { Int($0) }
print(compactMappedNumbers) // [1, 2, 4]
map 保留了 nil,所以结果是 [Optional(1), Optional(2), nil, Optional(4)]。
compactMap 丢弃了 nil,所以结果是 [1, 2, 4]。
适用场景
数据过滤和转换。
从可能返回 nil 的操作(如 Int($0)、URL(string:))中提取有效值。
清理嵌套数据结构中的无效值。
相关文章
Swift高阶函数map:https://fangjunyu.com/2024/12/21/swift%e9%ab%98%e9%98%b6%e5%87%bd%e6%95%b0map/