versiones guia español descargar actualizar ios arrays swift

ios - guia - qgis manual



Compruebe si la matriz opcional está vacía (7)

En Objective-C, cuando tengo una matriz

NSArray *array;

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

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

De esa manera, no es necesario verificar si array == nil ya que esta situación hará que el código caiga en el caso else , así como lo haría un array no nil pero vacío.

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

var array: [Int]?

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

Opción A: Marque los 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: desvincular 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 fusión que proporciona Swift:

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

No me gusta mucho la opción B , porque estoy repitiendo 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 algunos casos 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 señaló @vacawama, esta forma simple de verificarlo funciona:

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

Sin embargo, estaba probando 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 , por lo que las expresiones array?.count == 0 y array?.isEmpty == true evalúan como false .

Así que estoy tratando de averiguar si hay alguna forma de lograr esto con una sola condición también.


Propiedad de extensión en el protocolo de recopilació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 forzar el desenvolvimiento de las opcionales. Leí esto como desenvolver la matriz opcional y, si es nula, sustituir una matriz vacía del mismo tipo. Luego, tomando el resultado (no opcional) de eso y si está isEmpty ejecute 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 forzar el desenvolvimiento de las opciones cuando sea posible. Aunque está garantizado que la array nunca será nil cuando se ejecute array!.isEmpty en este caso específico, sería fácil editarlo más tarde e inadvertidamente introducir un bloqueo. Cuando se sienta cómodo con las opciones de desenvoltura forzada, aumentará la posibilidad de que alguien haga un cambio en el futuro que compila pero se bloquea en el tiempo 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 como:

¿Confuso?

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


Respuesta actualizada para Swift 3 y superior:

Swift 3 ha eliminado la capacidad de comparar opciones 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 forma más sencilla de verificar si una matriz opcional contiene valores es:

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

Otras formas 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 menos 6 opciones:

Opcion A:

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

Opcion B:

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

Opcion 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 es nulo o vacío". Le recomendaría que use esto, ya que es fácil de entender. No hay nada de malo en esto, especialmente porque "provocará un cortocircuito" y omitirá la comprobación de vacío si la variable es nil .

Respuesta anterior para Swift 2.x:

Simplemente puedes hacer:

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

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

De manera similar, podrías hacer:

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

Nota: Tienes que comparar explícitamente con false aquí para que esto funcione.

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

Opcion A:

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

Opcion B:

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

Opcion 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 es nulo o vacío". Le recomendaría que use esto, ya que es fácil de entender. No hay nada de malo en esto, especialmente porque "provocará un cortocircuito" y omitirá la comprobación de vacío si la variable es nil .


Desenvoltura 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''


En lugar de usar if y else , es mejor usar solo guard para verificar la matriz vacía sin crear nuevas variables para la misma matriz.

guard !array.isEmpty else { return } // do something with non empty ‘array’


La elegante solución incorporada es el método de map opcional. Este método a menudo se olvida, pero hace exactamente lo que necesita aquí; le permite enviar un mensaje a la cosa envuelta dentro de un Opcional, de forma segura. Terminamos en este caso con una especie de interruptor de tres vías: podemos decir isEmpty a la matriz Opcional, y obtener verdadero, falso o nulo (en caso de que la matriz sea nula).

var array : [Int]? array.map {$0.isEmpty} // nil (because `array` is nil) array = [] array.map {$0.isEmpty} // true (wrapped in an Optional) array?.append(1) array.map {$0.isEmpty} // false (wrapped in an Optional)


Swift 3-4 compatible:

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

Uso:

guard let array = myObject?.array.nilIfEmpty else { return }

O

if myObject.array.isNilOrEmpty { // Do stuff here }


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

var array = [Int]()

Ahora siempre existirá, y simplemente puede verificar isEmpty .