Chen Li Yong
Chen Li Yong

Reputation: 6107

How to create an extension of Collection that removes null values?

I have this code, but it shows error:

extension Collection {

    func removingOptionals() -> [Element] {
        var result = [Element](); // Error: cannot call value of non-function type '[Self.Element.Type]'
        self.forEach({ (element) in if let el = element { result.append(el); } });
        return result;
    }

}

If I removed the (), the error becomes: Expected member name or constructor call after type name.

This code is supposed to transform [String?] into [String] by discarding all the null values. Or any other optional data types.

How can I do this?

Upvotes: 0

Views: 76

Answers (2)

Sealos
Sealos

Reputation: 562

You can continue to use the flatMap behavior of the Optional as the other answer shows, but it's going to be deprecated on the next Swift iteration.

If you want to add the extension to the collection type, you need to be a create a type to box the Optional (You can't extend Collection if the type is generic, like Optional).

protocol OptionalType {
    associatedtype Wrapped
    func map<U>(_ f: (Wrapped) throws -> U) rethrows -> U?
}

extension Optional: OptionalType {}

extension Collection where Iterator.Element: OptionalType {
    func removeNils() -> [Iterator.Element.Wrapped] {

        var result: [Iterator.Element.Wrapped] = []
        result.reserveCapacity(Int(self.count))

        for element in self {
            if let element = element.map({ $0 }) {
                result.append(element)
            }
        }

        return result
    }
}

Upvotes: 0

Taras Chernyshenko
Taras Chernyshenko

Reputation: 2829

You can use flatMap {} for this, instead of creation own function. Here is example of usage:

let strings: [String?] = ["One", nil, "Two"]
print(strings.flatMap { $0 })

And result will be ["One", "Two"]

Upvotes: 3

Related Questions