How to use swift flatMap to filter out optionals from an array

后端 未结 5 1944
野的像风
野的像风 2021-02-05 05:14

I\'m a little confused around flatMap (added to Swift 1.2)

Say I have an array of some optional type e.g.

let possibles:[Int?] = [nil, 1, 2, 3, nil, nil         


        
5条回答
  •  春和景丽
    2021-02-05 06:16

    Since Swift 4.1 you can use compactMap:

    let possibles:[Int?] = [nil, 1, 2, 3, nil, nil, 4, 5]
    let actuals = possibles.compactMap { $0 }
    

    (Swift 4.1 replaced some overloads of flatMap with compactmap. If you are interested in more detail on this then see for example: https://useyourloaf.com/blog/replacing-flatmap-with-compactmap/ )

    With Swift 2 b1, you can simply do

    let possibles:[Int?] = [nil, 1, 2, 3, nil, nil, 4, 5]
    let actuals = possibles.flatMap { $0 }
    

    For earlier versions, you can shim this with the following extension:

    extension Array {
        func flatMap(transform: Element -> U?) -> [U] {
            var result = [U]()
            result.reserveCapacity(self.count)
            for item in map(transform) {
                if let item = item {
                    result.append(item)
                }
            }
            return result
        }
    }
    

    One caveat (which is also true for Swift 2) is that you might need to explicitly type the return value of the transform:

    let actuals = ["a", "1"].flatMap { str -> Int? in
        if let int = str.toInt() {
            return int
        } else {
            return nil
        }
    }
    assert(actuals == [1])
    

    For more info, see http://airspeedvelocity.net/2015/07/23/changes-to-the-swift-standard-library-in-2-0-betas-2-5/

提交回复
热议问题