Tengo una variedad de diferentes tipos de controladores de vista. Quiero poder verificar si la matriz contiene varios tipos. En otras palabras, ¿hay alguna forma de simplificar el siguiente código de

for item in theArray
{
   if item is ViewControllerTypeA
   {
     ...
   }
}
for item in theArray
{
   if item is ViewControllerTypeB
   {
     ....
   }
}
for item in theArray
{
   if item is ViewControllerTypeC
   {
     ....
   }
}

A algo como

func doesArrayContainType(T)
{
    for item in theArray
   {
       if item is T
       {
        ....
       }
   }
}

¿Hay alguna forma de que se puedan usar genéricos para esto? Si es así, ninguno de los tutoriales o referencias sobre genéricos son de ayuda para esta situación particular que puedo ver.

0
Gruntcakes 17 feb. 2018 a las 02:16

2 respuestas

La mejor respuesta

Aquí tienes tres controladores diferentes.

class AViewController: UIViewController {}
class BViewController: UIViewController {}
class CViewController: UIViewController {}

Y una función que toma una variedad de carpetas y una variedad de tipos.

func arrayOf<T: UIViewController>(_ array: [T], containsTypes types: [T.Type]) -> Bool {
    return array.contains { vc in types.contains { $0 === type(of: vc) as T.Type } }
}

La función verifica si los tipos del controlador están contenidos dentro de la matriz de tipos dada. Si al menos uno de los tipos está allí, devolverá verdadero.

let controllers = [
    AViewController(),
    BViewController(),
    CViewController()
]

print(arrayOf(controllers, containsTypes: [ AViewController.self, BViewController.self ]))
print(arrayOf(controllers, containsTypes: [ CViewController.self ]))
0
Callam 17 feb. 2018 a las 02:42

Sí, puede pasar información de tipo a un método

extension Sequence {
    // gives you an array of elements that have the specified type
    func filterByType<T>(_ type: T.Type = T.self) -> [T] {
        return flatMap { $0 as? T }
    }
}

La función anterior le dará una lista de elementos de la secuencia de destino que coinciden con el tipo que desea buscar.

Puede usarlo con o sin el parámetro type, siempre que el compilador pueda inferir el tipo de resultado:

let mixedArray: [Any] = [1, "2", 3, "4"]

// you need to pass the `type` parameter
mixedArray.filterByType(Int.self) // [1, 3]

// you don't need to pass the `type` parameter as the compiler
// can infer T by looking at the sorounding context
let strings: [String] = mixedArray.filterByType() // ["2", "4"]
1
Cristik 17 feb. 2018 a las 06:48