在 Swift 4.1中 似乎flatMap已弃用。但是在 Swift 4.1中 有一个新方法compactMap正在做同样的事情?有了它,flatMap您可以变换集合中的每个对象,然后删除所有为零的项目。 像flatMap一样
flatMap
compactMap
let array = ["1", "2", nil] array.flatMap { $0 } // will return "1", "2"
像compactMap
let array = ["1", "2", nil] array.compactMap { $0 } // will return "1", "2"
compactMap 在做同样的事情。
这两种方法有什么区别?苹果为何决定重命名该方法?
Swift标准库为flatMap函数定义了3个重载:
Sequence.flatMap<S>(_: (Element) -> S) -> [S.Element] Optional.flatMap<U>(_: (Wrapped) -> U?) -> U? Sequence.flatMap<U>(_: (Element) -> U?) -> [U]
可以通过两种方式滥用最后一个重载函数: 考虑以下struct和array:
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数组中的年龄的数组,则可以使用以下两个函数:
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之前将其解包装)
map
第二种方法-符合收集协议的字符串: 认为您需要从people数组中获取人员姓名列表。您可以使用以下行:
let names = people.flatMap({$0.name})
如果您使用的是4.0之前的快速版本,则将获得以下内容的转换列表:
["Osame", "Masoud", "Mehdi"]
但在较新的版本中String符合Collection协议,因此,您对的使用flatMap()将匹配第一个重载函数,而不是第三个重载函数,并且将为您带来转换后的值的平坦结果:
String
Collection
flatMap()
["O", "s", "a", "m", "e", "M", "a", "s", "o", "u", "d", "M", "e", "h", "d", "i"]
结论:他们弃用了flatMap()的第三重载。 由于这些误用,迅速团队决定将第三重载弃用到flatMap函数。Optional到目前为止,他们针对需要处理s 的情况的解决方案是引入一个名为的新函数compactMap(),它将为您带来预期的结果。
Optional
compactMap()