Compruebe si la matriz opcional está vacía.

En Objective-C, cuando tengo una matriz

NSArray *array; 

y quiero verificar si no está vacío, siempre lo hago:

 if (array.count > 0) { NSLog(@"There are objects!"); } else { NSLog(@"There are no objects..."); } 

De esta forma, no hay necesidad de verificar si array == nil ya que esta situación hará que el código caiga en el caso else , así como una matriz no nil pero vacía.

Sin embargo, en Swift, he tropezado con la situación en la que tengo una matriz opcional:

 var array: [Int]? 

y no puedo determinar qué condición utilizar. Tengo algunas opciones, como:

Opción A: Verifique casos no nil y vacíos en la misma condición:

 if array != nil && array!.count > 0 { println("There are objects") } else { println("No objects") } 

Opción B: Desenlazar la matriz usando let :

 if let unbindArray = array { if (unbindArray.count > 0) { println("There are objects!") } else { println("There are no objects...") } } else { println("There are no objects...") } 

Opción C: utilizando el operador de coalescencia que Swift proporciona:

 if (array?.count ?? 0) > 0 { println("There are objects") } else { println("No objects") } 

No me gusta mucho la opción B porque repito el código en dos condiciones. Pero no estoy realmente seguro de si las opciones A y C son correctas o si debería usar cualquier otra forma de hacerlo.

Sé que el uso de una matriz opcional podría evitarse dependiendo de la situación, pero en algún caso podría ser necesario preguntar si está vacío. Entonces me gustaría saber cuál es la forma de hacerlo de la manera más simple.


EDITAR:

Como lo señaló @vacawama, esta forma simple de comprobar que funciona:

 if array?.count > 0 { println("There are objects") } else { println("No objects") } 

Sin embargo, estaba intentando el caso en el que quiero hacer algo especial solo cuando es nil o vacío, y luego continuar independientemente de si la matriz tiene elementos o no. Entonces intenté:

 if array?.count == 0 { println("There are no objects") } // Do something regardless whether the array has elements or not. 

Y también

 if array?.isEmpty == true { println("There are no objects") } // Do something regardless whether the array has elements or not. 

Pero, cuando la matriz es nil , no cae en el cuerpo if . Y esto se debe a que, en ese caso, array?.count == nil y array?.isEmpty == nil , entonces las expresiones array?.count == 0 y array?.isEmpty == true ambas evalúan a false .

Por lo tanto, estoy tratando de averiguar si hay alguna forma de lograr esto con una sola condición también.

Respuesta actualizada para Swift 3:

Swift 3 ha eliminado la posibilidad de comparar opcionales con > y < , por lo que algunas partes de la respuesta anterior ya no son válidas.

Todavía es posible comparar opcionales con == , por lo que la manera más directa de verificar si una matriz opcional contiene valores es:

 if array?.isEmpty == false { print("There are objects!") } 

Otras forms en que se puede hacer:

 if array?.count ?? 0 > 0 { print("There are objects!") } if !(array?.isEmpty ?? true) { print("There are objects!") } if array != nil && !array!.isEmpty { print("There are objects!") } if array != nil && array!.count > 0 { print("There are objects!") } if !(array ?? []).isEmpty { print("There are objects!") } if (array ?? []).count > 0 { print("There are objects!") } if let array = array, array.count > 0 { print("There are objects!") } if let array = array, !array.isEmpty { print("There are objects!") } 

Si desea hacer algo cuando la matriz es nil o está vacía, tiene al less 6 opciones:

Opción A:

 if !(array?.isEmpty == false) { print("There are no objects") } 

Opción B:

 if array == nil || array!.count == 0 { print("There are no objects") } 

Opción C:

 if array == nil || array!.isEmpty { print("There are no objects") } 

Opción D:

 if (array ?? []).isEmpty { print("There are no objects") } 

Opción E:

 if array?.isEmpty ?? true { print("There are no objects") } 

Opción F:

 if (array?.count ?? 0) == 0 { print("There are no objects") } 

La Opción C captura exactamente cómo lo describió en inglés: "Quiero hacer algo especial solo cuando está vacío o nulo". Recomendaría que uses esto ya que es fácil de entender. No hay nada malo con esto, especialmente dado que "cortocircuitará" y saltará la comprobación de vacío si la variable es nil .



Respuesta anterior para Swift 2.x:

Usted puede simplemente hacer:

 if array?.count > 0 { print("There are objects") } else { print("No objects") } 

Como @Martin señala en los comentarios, usa func ><T : _Comparable>(lhs: T?, rhs: T?) -> Bool que significa que el comstackdor envuelve 0 como Int? para que la comparación se pueda hacer con el lado izquierdo, que es un Int? debido a la llamada de encadenamiento opcional.

De manera similar, puede hacer lo siguiente:

 if array?.isEmpty == false { print("There are objects") } else { print("No objects") } 

Nota: debe compararse explícitamente con false aquí para que esto funcione.


Si desea hacer algo cuando la matriz es nil o está vacía, tiene al less 7 opciones:

Opción A:

 if !(array?.count > 0) { print("There are no objects") } 

Opción B:

 if !(array?.isEmpty == false) { print("There are no objects") } 

Opción C:

 if array == nil || array!.count == 0 { print("There are no objects") } 

Opción D:

 if array == nil || array!.isEmpty { print("There are no objects") } 

Opción E:

 if (array ?? []).isEmpty { print("There are no objects") } 

Opción F:

 if array?.isEmpty ?? true { print("There are no objects") } 

Opción G:

 if (array?.count ?? 0) == 0 { print("There are no objects") } 

La opción D captura exactamente cómo lo describió en inglés: "Quiero hacer algo especial solo cuando está vacío o nulo". Recomendaría que uses esto ya que es fácil de entender. No hay nada malo con esto, especialmente dado que "cortocircuitará" y saltará la comprobación de vacío si la variable es nil .

Opción D: si la matriz no tiene que ser opcional, porque solo le importa si está vacía o no, inicialícela como una matriz vacía en lugar de una opción:

 var array = [Int]() 

Ahora siempre existirá, y simplemente puede verificar si está isEmpty .

Desembalaje condicional:

 if let anArray = array { if !anArray.isEmpty { //do something } } 

EDITAR: Posible desde Swift 1.2:

 if let myArray = array where !myArray.isEmpty { // do something with non empty 'myArray' } 

EDITAR: Posible desde Swift 2.0:

 guard let myArray = array where !myArray.isEmpty else { return } // do something with non empty 'myArray' 

Propiedad de extensión en el protocolo de recostackción

* Escrito en Swift 3

 extension Optional where Wrapped: Collection { var isNilOrEmpty: Bool { switch self { case .some(let collection): return collection.isEmpty case .none: return true } } } 

Ejemplo de uso:

 if array.isNilOrEmpty { print("The array is nil or empty") } 

Otras opciones

Aparte de la extensión anterior, encuentro la siguiente opción más clara sin la fuerza de desenvolver los opcionales. Leí esto como desenvolver la matriz opcional y si no, sustituyendo una matriz vacía del mismo tipo. Luego, tomando el resultado (no opcional) de eso y si es isEmpty ejecuta el código condicional.

Recomendado

 if (array ?? []).isEmpty { print("The array is nil or empty") } 

Aunque lo siguiente se lee claramente, sugiero el hábito de evitar la fuerza de desenvolver los opcionales siempre que sea posible. Aunque está garantizado que esa array nunca será nil cuando se ejecuta array!.isEmpty en este caso específico, sería fácil editarlo más tarde e introducir accidentalmente un locking. Cuando te sientas cómodo, fuerza la opción de desenvolver los opcionales, aumentas la posibilidad de que alguien realice un cambio en el futuro que compile pero se cuelga en el time de ejecución.

¡No recomendado!

 if array == nil || array!.isEmpty { print("The array is nil or empty") } 

¿Encuentro opciones que incluyen array? (encadenamiento opcional) confuso tales como:

¿Confuso?

 if !(array?.isEmpty == false) { print("The array is nil or empty") } if array?.isEmpty ?? true { print("There are no objects") }