参考文章:Swift 4.1 迁移小技巧 —— CompactMap
Swift 4.1引入了compactMap
,这里简单说一下来由和迁移技巧。
为什么要有CompactMap?
原因1:
旧版的flatMap有两个功能:降维 和 过滤nil(违背了单一职责原则)
1.降维
let arr = [[1, 2, 3], [4, 5]]
let newArr = arr.flatMap { $0 }
// newArr 的值为 [1, 2, 3, 4, 5]
2.过滤nil
let arr = [1, 2, 3, nil, nil, 4, 5]
let newArr = arr.flatMap { $0 }
// newArr 的值为 [1, 2, 3, 4, 5]
原因2:
除了违背单一职责原则,flatMap
还包含了隐藏逻辑。
对可选的二维数组进行flatMap
会得到什么结果呢?
let arr1 = [[1, 2, 3], [4, 5], nil]
let flatArr1 = arr1.flatMap{$0}
let arr2 = [[1, 2, 3], [4, 5]]
let flatArr2 = arr2.flatMap{$0}
print(flatArr1) //[[1, 2, 3], [4, 5]]
print(flatArr2) //[1, 2, 3, 4, 5]
显而易见,flatMap
隐藏了逻辑“如果是可选类型,过滤nil,不降纬;否则降维”
由此提出compactMap
,以区分降维和过滤nil
compactMap
-> 过滤nil
flatMap
-> 降维
Swift 4.1迁移
升级Swift 4.1之后,会有大量flatMap is deprecated
的warning
只有过滤nil的flatMap
报警告,所以进行全局的方法名替换不可取。
迁移思路:重载系统方法 -> 使用xcode提供的refactor替换方法名
下面给出常用的flatMap
重载,包括Array
、Dictionary
和Set
extension Array {
func flatMap(_ transform: (Element) throws -> String?) rethrows -> [String] {
return []
}
func flatMap<ElementOfResult>(_ transform: (Element) throws -> ElementOfResult?) rethrows -> [ElementOfResult] {
return []
}
}
extension Set {
func flatMap(_ transform: (Element) throws -> String?) rethrows -> [String] {
return []
}
func flatMap<ElementOfResult>(_ transform: (Element) throws -> ElementOfResult?) rethrows -> [ElementOfResult] {
return []
}
}
extension Dictionary {
func flatMap(_ transform: ((key: Key, value: Value)) throws -> String?) rethrows -> [String] {
return []
}
func flatMap<ElementOfResult>(_ transform: ((key: Key, value: Value)) throws -> ElementOfResult?) rethrows -> [ElementOfResult] {
return []
}
}
extension Dictionary.Keys {
func flatMap(_ transform: (Key) throws -> String?) rethrows -> [String] {
return []
}
func flatMap<ElementOfResult>(_ transform: (Key) throws -> ElementOfResult?) rethrows -> [ElementOfResult] {
return []
}
}
extension Dictionary.Values {
func flatMap(_ transform: (Value) throws -> String?) rethrows -> [String] {
return []
}
func flatMap<ElementOfResult>(_ transform: (Value) throws -> ElementOfResult?) rethrows -> [ElementOfResult] {
return []
}
}
1.将extension
导入项目
2.选中flatMap
-> Refactor
-> Rename
3.将flatMap
改成compactMap
4.依次将重载方法改名,即可基本完成迁移
5.迁移完之后删除重载方法
如果上面的重载方法覆盖不了全部warning,应该剩下不多了,手动点掉吧。🙂
PS.
重载了泛型版本的flatMap
,还要多写一个String
版本?
因为系统有个String
版本的flatMap
,调用时会优先调用指定类型flatMap
以上。