Swift: exclua todos os elementos da matriz

108

Estou tentando excluir todos os elementos da matriz com um loop for como este:

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

Mas não funciona, recebo este erro antes de construir:

Esperado ';' na declaração 'para'

Mehmet
fonte
5
Simples. reinicialize a matriz ...
VJ

Respostas:

326

Existe um método (na verdade, uma função)

myArray.removeAll()
vadiana
fonte
1
Não sabia sobre isso, Graças +1
JamesG
11
@NoodleOfDeath Strictly falado Swift arrays são programas structe structs têm functionsclasses diferentes methods.
vadian
1
@vadian +1 para o esclarecimento. Esqueci que Arrays são struct. Codificador de Objective-C veterano aqui ...
NoodleOfDeath
1
você precisa chamar a função removeAll () ao sair de uma visão (viewcontroller) onde você a inicializou, ou ela vai embora por conta própria !?
Famic Tech
1
@FamicTech Depende: Se a visão for descarregada ela vai embora implicitamente, se a visão apenas desaparecer você tem que chamar removeAll(). No entanto, é uma boa prática (disciplina de memória) remover todos os dados desnecessários quando uma visualização desaparece.
vadian
17

Partindo do princípio de que a resposta de @vadian é a solução , gostaria apenas de salientar que seu código não funciona.

Em primeiro lugar, os índices de array são baseados em 0, então você deve reescrever o intervalo de acordo:

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

No entanto, essa implementação causará um travamento. Se você tiver uma matriz de 10 elementos, o último elemento ocupará a posição no índice 9.

Usando esse loop, na primeira iteração o elemento no índice 0 é removido e isso faz com que o último elemento deslize para baixo no índice 8.

Na próxima iteração, o elemento no índice 1 é removido e o último elemento desloca para baixo no índice 7. E assim por diante.

Em algum ponto do loop, uma tentativa de remover um elemento de um índice não existente fará com que o aplicativo trave.

Ao remover elementos de uma matriz em um loop, a melhor maneira de fazer isso é percorrendo-a na ordem inversa:

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

Isso garante que os elementos removidos não alterem a ordem ou o índice dos elementos ainda a serem processados.

Antonio
fonte
1
Existe uma função para remover todos os elementos em apenas uma linha. como a resposta de @vadian ...
VJ
3
@VJ foi o que escrevi na primeira linha da minha resposta :)
Antonio
+1 para uma solução que pode ser usada para remover uma instância particular de um objeto. Eu uso de 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 } }preferência não toda uma linha, mas o código deve ser compilado em uma linha
NoodleOfDeath
Porque não for _ in 0...<myArray.count { myArray.removeAtIndex(0) }? Não sei muito sobre eficiência ainda, mas dessa forma você não precisa inverter o intervalo, talvez seja mais rápido.
cbjeukendrup
Isso também funciona! O mesmo método em termos de eficiência, você remove do início ao invés do final, mas você salva uma variável :-)
Antonio
7

Está faltando a inpalavra - chave que está causando o erro. O código deve ser:

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

No entanto, isso não funcionará como você esperaria por alguns motivos:

  • O último índice válido é o count - 1que exigiria1..<myArray.count
  • Mais importante ainda, remover um elemento de uma matriz o encurta, alterando os índices a cada vez.

Se você está tentando remover todas as coisas da matriz, você deve fazer como outros sugeriram e usar:

myArray.removeAll()

No caso de você querer apenas o primeiro elemento e nada mais, você pode obter uma referência para o primeiro objeto, esvazie a matriz e adicione o objeto novamente:

var firstElement = myArray.first!
myArray.removeAll()
myArray.append(firstElement)
Kyle Decot
fonte
Desculpe, não vi "em" ... Fiz +1
VJ
1
(+1) para explicar o erro real. (-1) porque isso não funcionará, pois excluir um item torna o array mais curto. (Observe também que o último índice válido é count - 1).
Martin R
7

Se você realmente deseja limpar o array, a maneira mais simples é reinicializá-lo.

VJ
fonte
3

Seu código deve funcionar, ele está fora dos limites.

Swift 3

existingArray = []

Ao fazer isso, você reatribui uma matriz vazia à matriz existente e o tipo de dados é referido.

Como alternativa, você pode usar o removeAllque remove todos os elementos da matriz e fornece uma opção para manter a capacidade existente.

existingArray.removeAll()

Esta é uma mutatingfunção que significa que o array que chama o método será alterado (vazio).

Lorem Ipsum Dolor
fonte
2

Kyle está no caminho certo, mas seu código falhará à medida que os índices possíveis diminuem durante a enumeração, levando a índices ilegais.

Uma maneira de resolver isso é enumerar de trás para frente. Na rapidez, isso é feito usando passadas .

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

outra opção seria usar filter()

Swift 1.2

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

Swift 2

myArray = myArray.filter{ (obj) -> Bool in
    return false
}
vikingosegundo
fonte
Muito interessante! Eu não sabia sobrestride
Kyle Decot
1

Existe o método removeAllObjects () disponível no Swift 2

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

Para remover o elemento em um índice específico, use:

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

Para remover o último elemento, use:

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

Para remover elementos em um determinado intervalo, use:

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

Para remover um elemento específico, use:

Syntax : public func removeObject(anObject: AnyObject)

A captura de tela abaixo mostra a lista de métodos disponíveis na extensão NSMutableArray

Captura de tela 1

Jayprakash Dubey
fonte
0

Você também pode fazer isso:

for _ in myArray
{
    myArray.removeAtIndex(0)
}
Darth Flyeater
fonte
2
Essa solução é terrivelmente ineficiente - em cada iteração, todos os índices de objetos subsequentes são alterados. Além disso, não tenho certeza se essa implementação é segura. Pelo menos nas coleções Objective-C, a mutação durante a enumeração é proibida.
Borys Verebskyi
0

Para remover todos os dados de uma matriz

yourArrayData.removeAll()

PatelFab
fonte
0

Vadian tem a resposta correta em termos do que você está tentando realizar. O problema mostrado como resultado de seu exemplo de código é devido à maneira como você está tentando criar o forloop. Indexcomeçará em 0 por padrão. Adicionar um intervalo numérico depois não é a maneira correta de criar um loop for. É por isso que você está vendo o erro. Em vez disso, crie seu loop for da seguinte maneira:

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

Esperançosamente, esta resposta ajudará outros que são novos em Swift ou programação.

Josh Hrach
fonte
você deve usar a propriedade indices de matriz ao iterar a coleção. Nem todas as coleções começam no índice zero
Leo Dabus
0

Para remover todos os elementos do array

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