Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find item of specific type in array

Tags:

generics

swift

I want an extension on a Array where you can find an item that is of some type.

I tried like this:

  func findItem<U: Type>(itemToFind: U) -> AnyObject? {
    for item in self {
        if let obj = item as? itemToFind {
            return obj
        }
    }
    return nil
}

So I check if it is the same type and then I want to return the obj.

The error I get is:

Inheritance from non-protocol, non-class 'Type'.

How can I fix this that I can pass to the function ViewController.self and that I get back nil if not found or the viewcontroller that is in the array?

like image 636
user1007522 Avatar asked Aug 29 '16 12:08

user1007522


Video Answer


1 Answers

The syntax <U: Type> in this context means you're declaring a new generic placeholder U in your function signature, which inherits from (in the case of classes), or conforms to (in the case of protocols) Type.

As Type is neither a protocol nor class, I assume what you really want is an unconstrained generic placeholder, and instead want to pass in a given type as an argument to the function, which will define the type of U.

In this case, you'll want to use the metatype U.Type as the function input type (as well as U? for the function return type – as the return type will be the optional type of whatever type you pass into the function). For example:

extension Array {
    func firstElement<U>(ofType _: U.Type) -> U? {
        for element in self {
            if let element = element as? U {
                return element
            }
        }
        return nil
    }
}

let array : [Any] = [2, "bar", 3, "foo"]
print(array.firstElement(ofType: String.self)) // Optional("bar")

As a side note, this could be simplified slightly by using pattern matching in the for loop:

func firstElement<U>(ofType _: U.Type) -> U? {
    for case let element as U in self {
        return element
    }
    return nil
}
like image 170
Hamish Avatar answered Nov 15 '22 11:11

Hamish