Creating an extension to filter nils from an Array in Swift

Javawag picture Javawag · Jan 28, 2015 · Viewed 23.8k times · Source

I'm trying to write an extension to Array which will allow an array of optional T's to be transformed into an array of non-optional T's.

e.g. this could be written as a free function like this:

func removeAllNils(array: [T?]) -> [T] {
    return array
        .filter({ $0 != nil })   // remove nils, still a [T?]
        .map({ $0! })            // convert each element from a T? to a T
}

But, I can't get this to work as an extension. I'm trying to tell the compiler that the extension only applies to Arrays of optional values. This is what I have so far:

extension Array {
    func filterNils<U, T: Optional<U>>() -> [U] {
        return filter({ $0 != nil }).map({ $0! })
    }
}

(it doesn't compile!)

Answer

Chris Trevarthen picture Chris Trevarthen · Aug 11, 2015

As of Swift 2.0, you don't need to write your own extension to filter nil values from an Array, you can use flatMap, which flattens the Array and filters nils:

let optionals : [String?] = ["a", "b", nil, "d"]
let nonOptionals = optionals.flatMap{$0}
print(nonOptionals)

Prints:

[a, b, d]

Note:

There are 2 flatMap functions: