Is there a way to check if an array type is optional?

Let's say I want to write a method on Arraythat either returns a copy of an array if its type is not optional, or a subarray of expanded values ​​if its type is optional. To do this, I think I need to check if the array type is an Toptional type or not. For example, this simply returns a copy of the array anyway:

extension Array {        
    func unwrapped() -> Array<T> {
        return filter({
            var x: T? = $0
            return x != nil
        })
    }
}

I understand that if I know that I have an array of options, I could just use filter () and map ():

let foo: [String?] = [nil, "bar", "baz"]
let bar: [String] = foo.filter({ $0 != nil }).map({ $0! })

I am not looking for a solution to this particular problem. I rather wonder if there is a way to determine in the extension of the array if its type is optional, which may be useful in several different convenience methods.

+4
4

; : :

func unwrapped<T>(a: [T]) -> [T] { return a }
func unwrapped<T>(a: [T?]) -> [T] {
    return a.filter { $0 != nil }.map { $0! }
}

unwrapped([1, 2, 3, 4, 5]) // -> [1, 2, 3, 4, 5]
unwrapped([1, 2, 3, nil, 5]) // -> [1, 2, 3, 5]

, . , - , - Swift, , .

. .

+3

:

let unwrapped = foo.reduce([String]()) {
    if let bar = $1 as String? { return $0 + [bar] }
    return $0
}

, , -nil , . , .

, , :

extension Array {
    func optTest() {
        switch reflect(self[0]).disposition {
            case .Optional:
                println("I am an optional")
            default:
                break
        }
    }
}

. , - , , ...

0

Array , , Optional.

Swift 2, , .

protocol OptionalProtocol {}

extension Optional : OptionalProtocol {}

extension Array {
    func elementType() -> Any.Type {
        return Element.self
    }
}

[String]().elementType() is OptionalProtocol.Type  // false
[String?]().elementType() is OptionalProtocol.Type // true

Swift 2 Array , typealias Element:

protocol OptionalProtocol {}

extension Optional : OptionalProtocol {}

[String]().dynamicType.Element.self is OptionalProtocol.Type  // false
[String?]().dynamicType.Element.self is OptionalProtocol.Type // true
0

To do this, I think I need to check if the array type T is an optional type or not.

No, you don’t have to - just use flatMap!

let foo: [String?] = [nil, "bar", "baz"]
let foo2: [String] = ["bar", "baz"]

foo.flatMap{$0}
foo2.flatMap{$0}
// yield both ["bar", "baz"] and are of type Array<String>
0
source

Source: https://habr.com/ru/post/1543625/


All Articles