Nareshkumar
Nareshkumar

Reputation: 2351

Swift return object of type from an array containing class elements

Here is a small code I wrote to explain the problem:

class Vehicle{
    var name:String = ""
    var tyres: Int = 0

}

class Bus:Vehicle{
    var make:String = "Leyland"
}

class Car: Vehicle{
    var model:String = "Polo"
}

let myVehicles:[Vehicle] = [
    Vehicle(),
    Car(),
    Bus()
]

for aVehicle in myVehicles{
    if(aVehicle is Bus){
        print("Bus found")
    }
}

From the code, I can loop through and get the object of type Bus. However, I need a function to do the same thing and return the element of that type if available. I tried using generics but it does not work. I will need something like this:

func getVehicle(type:T.type)->T?{
 // loop through the array, find if the object is of the given type.
 // Return that type object.
}

Upvotes: 3

Views: 2293

Answers (4)

Kane Cheshire
Kane Cheshire

Reputation: 1712

You can also use this:

func getVehicle<T>(type: T.Type) -> T? {
  return myVehicles.filter { Swift.type(of: $0) == type }.first as? T
}

Usage:

getVehicle(type: Bus.self)

Upvotes: 1

YanSte
YanSte

Reputation: 10839

You can also use this:

let a = array.compactMap({ $0 as? MyTypeClass })
// a == [MyTypeClass] no optional 

Upvotes: 1

kennytm
kennytm

Reputation: 523394

Use foo as? T to try to cast foo as type T.

for aVehicle in myVehicles{
    if let bus = aVehicle as? Bus {
        print("Bus found", bus.make)
    }
}

Your getVehicle can thus be written as:

func getVehicle<T>() -> T? {
    for aVehicle in myVehicles {
        if let v = aVehicle as? T {
            return v
        }
    }
    return nil
}

let bus: Bus? = getVehicle()

or functionally:

func getVehicle<T>() -> T? {
    return myVehicles.lazy.flatMap { $0 as? T }.first
}
let bus: Bus? = getVehicle()

(Note that we need to specify the returned variable as Bus? so getVehicle can infer the T.)

Upvotes: 4

Oleg Gordiichuk
Oleg Gordiichuk

Reputation: 15512

You can write it like this :

 func getVehicle<T>(type:T)-> [T]{
    return myVehicles.filter{ $0 is T }.map{$0 as! T }
 }

Upvotes: 3

Related Questions