參考文章:Swift 4.1 遷移小技巧 —— CompactMap
Swift 4.1引入了compactMap,這里簡(jiǎn)單說(shuō)一下來(lái)由和遷移技巧。
為什么要有CompactMap?
原因1:
舊版的flatMap有兩個(gè)功能:降維 和 過(guò)濾nil(違背了單一職責(zé)原則)
1.降維
let arr = [[1, 2, 3], [4, 5]]
let newArr = arr.flatMap { $0 }
// newArr 的值為 [1, 2, 3, 4, 5]
2.過(guò)濾nil
let arr = [1, 2, 3, nil, nil, 4, 5]
let newArr = arr.flatMap { $0 }
// newArr 的值為 [1, 2, 3, 4, 5]
原因2:
除了違背單一職責(zé)原則,flatMap還包含了隱藏邏輯。
對(duì)可選的二維數(shù)組進(jìn)行flatMap會(huì)得到什么結(jié)果呢?
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]
顯而易見(jiàn),flatMap隱藏了邏輯“如果是可選類型,過(guò)濾nil,不降緯;否則降維”
由此提出compactMap,以區(qū)分降維和過(guò)濾nil
compactMap -> 過(guò)濾nil
flatMap -> 降維
Swift 4.1遷移
升級(jí)Swift 4.1之后,會(huì)有大量flatMap is deprecated的warning
只有過(guò)濾nil的flatMap報(bào)警告,所以進(jìn)行全局的方法名替換不可取。

遷移思路:重載系統(tǒng)方法 -> 使用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導(dǎo)入項(xiàng)目
2.選中flatMap -> Refactor -> Rename
3.將flatMap改成compactMap
4.依次將重載方法改名,即可基本完成遷移
5.遷移完之后刪除重載方法

如果上面的重載方法覆蓋不了全部warning,應(yīng)該剩下不多了,手動(dòng)點(diǎn)掉吧。??
PS.
重載了泛型版本的flatMap,還要多寫一個(gè)String版本?
因?yàn)橄到y(tǒng)有個(gè)String版本的flatMap,調(diào)用時(shí)會(huì)優(yōu)先調(diào)用指定類型flatMap
以上。