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

后端 未结 5 1993
野的像风
野的像风 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 05:53

    I still like the first solution, which creates only one intermediate array. It can slightly more compact be written as

    let filtermap = possibles.filter({ $0 != nil }).map({ $0! })
    

    But flatMap() without type annotation and without forced unwrapping is possible:

    var flatmap3 = possibles.flatMap {
        flatMap($0, { [$0] }) ?? []
    }
    

    The outer flatMap is the array method

    func flatMap(transform: @noescape (T) -> [U]) -> [U]
    

    and the inner flatMap is the function

    func flatMap(x: T?, f: @noescape (T) -> U?) -> U?
    

    Here is a simple performance comparison (compiled in Release mode). It shows that the first method is faster, approximately by a factor of 10:

    let count = 1000000
    let possibles : [Int?] = map(0 ..< count) { $0 % 2 == 0 ? $0 : nil }
    
    let s1 = NSDate()
    let result1 = possibles.filter({ $0 != nil }).map({ $0! })
    let e1 = NSDate()
    println(e1.timeIntervalSinceDate(s1))
    // 0.0169369578361511
    
    let s2 = NSDate()
    var result2 = possibles.flatMap {
        flatMap($0, { [$0] }) ?? []
    }
    let e2 = NSDate()
    println(e2.timeIntervalSinceDate(s2))
    // 0.117663979530334
    

提交回复
热议问题