I am implementing a function called ofType
which filters out all the elements of the given type.
Here are my codes:
class Animal {}
class Mammal: Animal {}
class Monkey: Mammal {}
class Pig: Mammal {}
class Human: Mammal {}
extension Array {
func ofType<T>(_ metatype: T.Type) -> [T] {
return flatMap { type(of: $0) == metatype ? $0 as? T : nil }
// return flatMap { $0 as? T } // This is not working as the T is always the static type of the parameter, which is Animal in this example.
// return flatMap { $0 as? metatype } // This is not working either because of the grammar restriction.
}
}
let animals = [Monkey(), Pig(), Human(), Mammal(), Animal()]
func animalType() -> Animal.Type {
return Mammal.self
}
animals.ofType(animalType()).count // returns 1, expect to be 4.
In Objc, I can use isKindOf()
to check whether an object is an instance of the class or the subclass. There are similar operations in swift is
and as
, but the type after them should be a static type, not a dynamic type value (e.g. I can write is Mammal
, but not is Mammal.self
).
I cannot use the type parameter T
either because, in this example, the T
equals to Animal
, which is not what I want.
Do you have any idea about how to implement this function?