Bil*_*fas 21 swift swift4 swift4.1
似乎在Swift 4.1 flatMap中已弃用.然而,Swift 4.1中 有一个新方法,compactMap它做同样的事情?有了flatMap你可以集合中变换的每个对象,然后删除在无任何项目.
像flatMap一样
let array = ["1", "2", nil]
array.flatMap { $0 } // will return "1", "2"
Run Code Online (Sandbox Code Playgroud)
就像compactMap一样
let array = ["1", "2", nil]
array.compactMap { $0 } // will return "1", "2"
Run Code Online (Sandbox Code Playgroud)
compactMap 正在做同样的事情.
这两种方法有什么区别?为什么Apple决定重命名该方法?
Meh*_*hdi 21
Swift标准库为flatMap函数定义了3个重载:
Sequence.flatMap<S>(_: (Element) -> S) -> [S.Element]
Optional.flatMap<U>(_: (Wrapped) -> U?) -> U?
Sequence.flatMap<U>(_: (Element) -> U?) -> [U]
Run Code Online (Sandbox Code Playgroud)
最后一个重载函数可能会以两种方式被滥用:
请考虑以下结构和数组:
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")]
Run Code Online (Sandbox Code Playgroud)
第一种方式:额外的包装和展开:
如果您需要获得阵列中包含的people一系列人员,您可以使用两个功能:
let flatMappedAges = people.flatMap({$0.age}) // prints: [21, 17, 20]
let mappedAges = people.map({$0.age}) // prints: [21, 17, 20]
Run Code Online (Sandbox Code Playgroud)
在这种情况下,该map函数将完成工作并且不需要使用flatMap,因为两者都产生相同的结果.此外,在flatMap的这个用例中有一个无用的包装和解包过程.(closure参数用一个Optional包装它返回的值,flatMap的实现在返回之前展开Optional值)
第二种方式 - 字符串与集合协议的一致性:
认为你需要从people数组中获取人名的列表.您可以使用以下行:
let names = people.flatMap({$0.name})
Run Code Online (Sandbox Code Playgroud)
如果您使用4.0之前的swift版本,您将获得转换后的列表
["Osame", "Masoud", "Mehdi"]
Run Code Online (Sandbox Code Playgroud)
但是在较新的版本中String符合Collection协议,因此,您的使用flatMap()将匹配第一个重载函数而不是第三个重载函数,并且会为您提供转换后的值的展平结果:
["O", "s", "a", "m", "e", "M", "a", "s", "o", "u", "d", "M", "e", "h", "d", "i"]
Run Code Online (Sandbox Code Playgroud)
结论:他们弃用了flatMap的第三个重载()
由于这些误用,swift团队决定弃用flatMap函数的第三个重载.他们对你需要处理Optionals 的情况的解决方案是引入一个新的函数compactMap(),它会给你预期的结果.
Bil*_*lal 19
有三种不同的变体flatMap.它的变体Sequence.flatMap(_:)接受一个返回Optional值的闭包已被弃用.flatMap(_:)Sequence和Optional上的其他变体保持不变.提案文件中解释的原因是由于滥用.
flatMap在新方法下,不推荐使用的变体功能完全相同compactMap.
详情请见此处.