Swift 4.1迁移 flatMap to compactMap

参考文章: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
只有过滤nilflatMap报警告,所以进行全局的方法名替换不可取。

迁移思路:重载系统方法 -> 使用xcode提供的refactor替换方法名

下面给出常用的flatMap重载,包括ArrayDictionarySet


extension Array {
    func flatMap(_ transform: (Element) throws -> String?) rethrows -> [String] {
        return []
    }
    
    func flatMap(_ transform: (Element) throws -> ElementOfResult?) rethrows -> [ElementOfResult] {
        return []
    }
}

extension Set {
    func flatMap(_ transform: (Element) throws -> String?) rethrows -> [String] {
        return []
    }
    
    func flatMap(_ transform: (Element) throws -> ElementOfResult?) rethrows -> [ElementOfResult] {
        return []
    }
}

extension Dictionary {
    func flatMap(_ transform: ((key: Key, value: Value)) throws -> String?) rethrows -> [String] {
        return []
    }
    
    func flatMap(_ transform: ((key: Key, value: Value)) throws -> ElementOfResult?) rethrows -> [ElementOfResult] {
        return []
    }
}

extension Dictionary.Keys {
    func flatMap(_ transform: (Key) throws -> String?) rethrows -> [String] {
        return []
    }
    
    func flatMap(_ transform: (Key) throws -> ElementOfResult?) rethrows -> [ElementOfResult] {
        return []
    }
}

extension Dictionary.Values {
    func flatMap(_ transform: (Value) throws -> String?) rethrows -> [String] {
        return []
    }
    
    func flatMap(_ 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

以上。

你可能感兴趣的:(Swift 4.1迁移 flatMap to compactMap)