Swift: eliminar todos los elementos de la matriz

108

Estoy tratando de eliminar todos los elementos de la matriz con un bucle for como este:

for index 1...myArray.count {
   myArray.removeAtIndex(index)
}

Pero no funciona, obtengo este error antes de construir:

Esperado ';' en la declaración 'for'

Mehmet
fuente
5
Sencillo. reinicializar la matriz ...
VJ

Respuestas:

326

Hay un método (en realidad una función)

myArray.removeAll()
vadian
fuente
1
No sabía sobre esto, gracias +1
JamesG
11
@NoodleOfDeath Las matrices Swift estrictamente habladas son structsy las estructuras tienen functionsclases diferentes a las que tienen methods.
vadian
1
@vadian +1 para la aclaración. Olvidé los Arrays son structs.
Codificador
1
¿Necesita llamar a la función removeAll () al salir de una vista (viewcontroller) donde lo inicializa, o desaparece por sí solo?
Famic Tech
1
@FamicTech Depende: Si la vista está descargada desaparece implícitamente, si la vista solo desaparece hay que llamar removeAll(). Sin embargo, es una buena práctica (disciplina de memoria) eliminar todos los datos innecesarios cuando desaparece una vista.
vadian
17

Dando por sentado que la respuesta de @ vadian es la solución , solo me gustaría señalar que su código no funciona.

En primer lugar, los índices de matriz están basados ​​en 0, por lo que debe reescribir el rango en consecuencia:

for index 0..<myArray.count {
   myArray.removeAtIndex(index)
}

Sin embargo, esta implementación provocará un bloqueo. Si tiene una matriz de 10 elementos, el último elemento ocupa la posición en el índice 9.

Usando ese ciclo, en la primera iteración se elimina el elemento en el índice 0, y eso hace que el último elemento se desplace hacia abajo en el índice 8.

En la siguiente iteración, el elemento del índice 1 se elimina y el último elemento se desplaza hacia abajo en el índice 7. Y así sucesivamente.

En algún punto del ciclo, un intento de eliminar un elemento de un índice no existente hará que la aplicación se bloquee.

Al eliminar elementos de una matriz en un bucle, la mejor forma de hacerlo es atravesarlo en orden inverso:

for index in reverse(0..<myArray.count) {
    myArray.removeAtIndex(index)
}

Eso garantiza que los elementos eliminados no cambien el orden o el índice de los elementos que aún deben procesarse.

Antonio
fuente
1
Hay una función para eliminar todos los elementos en una sola línea. como la respuesta de @ vadian ...
VJ
3
@VJ eso es lo que escribí en la primera línea de mi respuesta :)
Antonio
+1 para una solución que se puede usar para eliminar una instancia particular de un objeto. public extension Array where Element : Equatable { public mutating func remove(element: Element) -> Int { var occurrences = 0; for index in (0 ..< count).reverse() { if self[index] == element { removeAtIndex(index); occurrences += 1 } }; return occurrences } }Preferiblemente no uso toda una línea, pero ese código debe compilarse en una línea
NoodleOfDeath
¿Por qué no for _ in 0...<myArray.count { myArray.removeAtIndex(0) }? Todavía no sé mucho sobre eficiencia, pero de esta manera no es necesario invertir el rango, por lo que tal vez sea más rápido.
cbjeukendrup
¡Eso también funciona! El mismo método en términos de eficiencia, elimina desde el principio en lugar del final, pero guarda una variable :-)
Antonio
7

Falta la inpalabra clave que está causando el error. El código debe ser:

for index in 1...myArray.count {
    myArray.removeAtIndex(index)
}

Sin embargo, esto no funcionará como cabría esperar por un par de razones:

  • El último índice válido es el count - 1que requeriría1..<myArray.count
  • Más importante aún, eliminar un elemento de una matriz lo acorta y, por lo tanto, cambia los índices cada vez.

Si está tratando de eliminar todas las cosas de la matriz, debe hacer lo que otros han sugerido y usar:

myArray.removeAll()

En el caso de que solo desee el primer elemento y nada más, puede obtener una referencia al primer objeto, vacíe la matriz y luego vuelva a agregar el objeto:

var firstElement = myArray.first!
myArray.removeAll()
myArray.append(firstElement)
Kyle Decot
fuente
Lo siento, no vi "en" ... Hice +1
VJ
1
(+1) para explicar el error real. (-1) porque esto no funcionará, ya que eliminar un elemento acorta la matriz. (Tenga en cuenta también que el último índice válido es count - 1).
Martin R
7

Si realmente desea borrar la matriz, la forma más sencilla es reinicializarla.

VJ
fuente
3

Su código debería funcionar, simplemente está fuera de límites.

Swift 3

existingArray = []

Al hacer esto, reasigna una matriz vacía a la matriz existente y se hace referencia al tipo de datos.

Alternativamente, puede usar lo removeAllque elimina todos los elementos de la matriz y proporciona una opción para mantener la capacidad existente.

existingArray.removeAll()

Esta es una mutatingfunción que significa que la matriz que llama al método será cambiada (vacía).

Lorem
fuente
2

Kyle está en el camino correcto, pero su código fallará ya que los índices posibles se reducen durante la enumeración, lo que genera índices ilegales.

Una forma de resolverlo es enumerar al revés. Con rapidez, esto se hace usando zancadas .

for index in stride(from: myArray.count - 1, through: 0, by: -1) {
    myArray.removeAtIndex(index)
}

otra opción sería usar filter()

Swift 1.2

myArray = filter(myArray, { (obj) -> Bool in
    return false
})

Swift 2

myArray = myArray.filter{ (obj) -> Bool in
    return false
}
vikingosegundo
fuente
¡Muy interesante! No sabía sobrestride
Kyle Decot
1

Hay un método removeAllObjects () disponible en Swift 2

Syntax :  public func removeAllObjects()
Eg.:   mainArray.removeAllObjects

Para eliminar un elemento en un índice particular, use:

Syntax : public func removeObjectAtIndex(index: Int)
Eg.: mainArray.removeObjectAtIndex(5)

Para eliminar el uso del último elemento:

Syntax : public func removeLastObject()
Eg.: mainArray.removeLastObject()

Para eliminar elementos en un rango particular, use:

Syntax : public func removeObject(anObject: AnyObject, inRange range: NSRange)

Para eliminar el uso de un elemento en particular:

Syntax : public func removeObject(anObject: AnyObject)

La siguiente captura de pantalla muestra la lista de métodos disponibles en la extensión NSMutableArray

Captura de pantalla 1

Jayprakash Dubey
fuente
0

También puedes hacer esto:

for _ in myArray
{
    myArray.removeAtIndex(0)
}
Flyeater de Darth
fuente
2
Esta solución es terriblemente ineficaz: en cada iteración, todos los índices de objetos posteriores se desplazan. Además, no estoy seguro de que esta implementación sea segura. Al menos en las colecciones de Objective-C está prohibida la mutación durante la enumeración.
Borys Verebskyi
0

Para eliminar todos los datos de una matriz

yourArrayData.removeAll()

Ronak
fuente
0

Vadian tiene la respuesta correcta en términos de lo que está tratando de lograr. El problema que se muestra como resultado de su ejemplo de código se debe a la forma en que está intentando crear el forbucle. Indexcomenzará en 0 por defecto. Agregar un rango de números después no es la forma correcta de crear un bucle for. Por eso ves el error. En su lugar, cree su bucle for de la siguiente manera:

for index in myArray.indices {
    // Do stuff
}

Con suerte, esta respuesta ayudará a otros que son nuevos en Swift o en programación.

Josh Hrach
fuente
debe usar la propiedad de índices de matriz al iterar la colección. No todas las colecciones comienzan en el índice cero
Leo Dabus
0

Para eliminar todos los elementos de la matriz

var array = [1,2,3,4,5,6]()
array.removeAll()
Imran Rasheed
fuente