tutorial que programar desde desarrollo curso coursera con color cero bar aplicaciones ios arrays swift enumeration

programar - swift ios que es



¿Eliminar de la matriz durante la enumeración en Swift? (8)

Quiero enumerar a través de una matriz en Swift y eliminar ciertos elementos. Me pregunto si es seguro hacerlo, y si no, cómo se supone que lo logre.

Actualmente, estaría haciendo esto:

for (index, aString: String) in enumerate(array) { //Some of the strings... array.removeAtIndex(index) }


Cree una matriz mutable para almacenar los elementos que se eliminarán y luego, después de la enumeración, elimine esos elementos del original. O cree una copia de la matriz (inmutable), enumere eso y elimine los objetos (no por índice) del original mientras lo enumera.


Cuando un elemento en un cierto índice se elimina de una matriz, todos los elementos subsiguientes tendrán su posición (e índice) cambiados, ya que retroceden una posición.

Entonces, la mejor manera es navegar por la matriz en orden inverso, y en este caso sugiero usar un bucle for tradicional:

for var index = array.count - 1; index >= 0; --index { if condition { array.removeAtIndex(index) } }

Sin embargo, en mi opinión, el mejor enfoque es usar el método de filter , como lo describe @perlfly en su respuesta.


El bucle for tradicional podría reemplazarse por un bucle while simple, útil si también necesita realizar otras operaciones en cada elemento antes de eliminarlo.

var index = array.count-1 while index >= 0 { let element = array[index] //any operations on element array.remove(at: index) index -= 1 }


En Swift 3 y 4 , esto sería:

Con números, según la respuesta de Johnston:

var a = [1,2,3,4,5,6] for (i,num) in a.enumerated().reversed() { a.remove(at: i) } print(a)

Con cadenas como la pregunta del OP:

var b = ["a", "b", "c", "d", "e", "f"] for (i,str) in b.enumerated().reversed() { if str == "c" { b.remove(at: i) } } print(b)

Sin embargo, ahora en Swift 4.2 o posterior, hay una forma mejor y más rápida que Apple recomendó en WWDC2018:

var c = ["a", "b", "c", "d", "e", "f"] c.removeAll(where: {$0 == "c"}) print(c)

Esta nueva forma tiene varias ventajas:

  1. Es más rápido que las implementaciones con filter .
  2. Elimina la necesidad de invertir las matrices.
  3. Elimina los elementos in situ y, por lo tanto, actualiza la matriz original en lugar de asignar y devolver una nueva matriz.

En Swift 2 esto es bastante fácil usando enumerate y reverse .

var a = [1,2,3,4,5,6] for (i,num) in a.enumerate().reverse() { a.removeAtIndex(i) } print(a)

Vea mi swiftstub aquí: http://swiftstub.com/944024718/?v=beta


No, no es seguro mutar matrices durante la enumeración, su código se bloqueará.

Si desea eliminar solo unos pocos objetos, puede usar la función de filter .


Puede considerar la forma de filter :

var theStrings = ["foo", "bar", "zxy"] // Filter only strings that begins with "b" theStrings = theStrings.filter { $0.hasPrefix("b") }

El parámetro de filter es solo un cierre que toma una instancia de tipo de matriz (en este caso, String ) y devuelve un Bool . Cuando el resultado es true , mantiene el elemento; de lo contrario, el elemento se filtra.


Recomiendo establecer elementos en cero durante la enumeración, y después de completar eliminar todos los elementos vacíos utilizando el método de matriz de filtros ().