Swift 标准库定义了 3 个重载flatMap
功能:
Sequence.flatMap<S>(_: (Element) -> S) -> [S.Element]
Optional.flatMap<U>(_: (Wrapped) -> U?) -> U?
Sequence.flatMap<U>(_: (Element) -> U?) -> [U]
最后一个重载函数可能会通过两种方式被滥用:
考虑以下结构和数组:
struct Person {
var age: Int
var name: String
}
let people = [
Person(age: 21, name: "Osame"),
Person(age: 17, name: "Masoud"),
Person(age: 20, name: "Mehdi")
]
第一种方式:附加包装和展开:
如果您需要获取包含在其中的一系列年龄的人员people
数组你可以使用两个函数:
let flatMappedAges = people.flatMap({$0.age}) // prints: [21, 17, 20]
let mappedAges = people.map({$0.age}) // prints: [21, 17, 20]
在这种情况下map
函数即可完成工作,无需使用flatMap
,因为两者产生相同的结果。此外,在 flatMap 的这个用例中,还有一个无用的包装和解包过程。(闭包参数用一个Optional来包装它的返回值,而flatMap的实现在返回它之前解开Optional值)
第二种方式 - 字符串符合收集协议:
认为您需要从中获取人员姓名列表people
大批。您可以使用以下行:
let names = people.flatMap({$0.name})
如果您使用 4.0 之前的 swift 版本,您将获得一个转换后的列表
["Osame", "Masoud", "Mehdi"]
但在较新的版本中String
符合Collection
协议,所以,你的使用flatMap()
将匹配第一个重载函数而不是第三个重载函数,并为您提供转换值的扁平化结果:
["O", "s", "a", "m", "e", "M", "a", "s", "o", "u", "d", "M", "e", "h", "d", "i"]
那么,他们是如何解决的呢?他们弃用了 flatMap() 的第三次重载
由于这些误用,swift 团队决定弃用 flatMap 函数的第三个重载。以及他们对您需要处理的情况的解决方案Optional
到目前为止,我们引入了一个新函数,称为compactMap()
这会给你预期的结果。