Swift: usuń wszystkie elementy tablicy


108

Próbuję usunąć wszystkie elementy tablicy za pomocą pętli for w następujący sposób:

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

Ale to nie działa, pojawia się ten błąd przed budowaniem:

Spodziewany ';' w wyrażeniu „for”


5
Prosty. ponownie zainicjuj tablicę ...
VJ,

Odpowiedzi:


326

Jest metoda (właściwie funkcja)

myArray.removeAll()

1
Nie wiedziałem o tym, dzięki +1
JamesG,

12
@NoodleOfDeath Ściśle mówione tablice Swift są structsi, a struktury mają w functionsprzeciwieństwie do klas, które mają methods.
Vadian

1
@vadian +1 dla wyjaśnienia. Zapomniałem, Arrayże są structs. Weteran kodujący Objective-C tutaj ...
NoodleOfDeath

1
czy musisz wywoływać funkcję removeAll () podczas wychodzenia z widoku (viewcontroller), w którym ją inicjalizujesz, czy też znika ona sama !?
Famic Tech

1
@FamicTech To zależy: jeśli widok jest rozładowany, znika niejawnie, jeśli tylko widok znika, musisz zadzwonić removeAll(). Jednak dobrą praktyką (dyscyplina pamięci) jest usuwanie wszystkich niepotrzebnych danych, gdy widok znika.
vadian

17

Zakładając, że odpowiedź @ vadian jest rozwiązaniem , chciałbym tylko zaznaczyć, że Twój kod nie działa.

Przede wszystkim indeksy tablic są oparte na 0, więc należy odpowiednio przepisać zakres:

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

Jednak ta implementacja spowoduje awarię. Jeśli masz tablicę 10 elementów, ostatni element zajmuje pozycję pod indeksem 9.

Używając tej pętli, w pierwszej iteracji element o indeksie 0 jest usuwany, co powoduje, że ostatni element przesuwa się w dół o indeksie 8.

W następnej iteracji element pod indeksem 1 jest usuwany, a ostatni element przesuwa się w dół pod indeksem 7. I tak dalej.

W pewnym momencie pętli próba usunięcia elementu dla nieistniejącego indeksu spowoduje awarię aplikacji.

Podczas usuwania elementów z tablicy w pętli najlepszym sposobem na zrobienie tego jest przejście w odwrotnej kolejności:

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

Gwarantuje to, że usunięte elementy nie zmieniają kolejności ani indeksu elementów, które nadal mają być przetworzone.


1
Istnieje funkcja usuwania wszystkich elementów w jednej linii. as @ vadian's answer ...
VJ

3
@VJ tak napisałem w pierwszej linijce mojej odpowiedzi :)
Antonio

+1 za rozwiązanie, którego można użyć do usunięcia określonej instancji obiektu. Używam 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 } }korzystnie nie tylko jeden wiersz, ale że kod powinien skompilować na jednej linii
NoodleOfDeath

Dlaczego nie for _ in 0...<myArray.count { myArray.removeAtIndex(0) }? Nie wiem jeszcze zbyt wiele o skuteczności, ale w ten sposób nie trzeba odwracać zasięgu, więc może jest szybszy.
cbjeukendrup

To też działa! Ta sama metoda pod względem wydajności, usuwasz od początku zamiast końca, ale zapisujesz zmienną :-)
Antonio

7

Brakuje insłowa kluczowego, które powoduje błąd. Kod powinien być:

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

Nie zadziała to jednak tak, jak można by się tego spodziewać z kilku powodów:

  • Ostatnim ważnym indeksem jest to, count - 1co by wymagało1..<myArray.count
  • Co ważniejsze, usunięcie elementu z tablicy skraca go, zmieniając za każdym razem indeksy.

Jeśli próbujesz usunąć wszystkie rzeczy z tablicy, powinieneś zrobić tak, jak inni sugerowali i użyć:

myArray.removeAll()

W przypadku, gdy chcesz tylko pierwszy element i nic innego nie możesz uzyskać odniesienia do pierwszego obiektu, opróżnij tablicę, a następnie dodaj obiekt z powrotem:

var firstElement = myArray.first!
myArray.removeAll()
myArray.append(firstElement)

Przepraszam, że nie widziałem „w” ... Zrobiłem +1
VJ

1
(+1) za wyjaśnienie rzeczywistego błędu. (-1), ponieważ to nie zadziała, ponieważ usunięcie elementu powoduje skrócenie tablicy. (Zauważ również, że ostatni prawidłowy indeks to count - 1).
Martin R

7

Jeśli naprawdę chcesz wyczyścić tablicę, najprostszym sposobem jest ponowne zainicjowanie jej.


3

Twój kod powinien działać, po prostu jest poza zakresem.

Szybki 3

existingArray = []

W ten sposób ponownie przypisujesz pustą tablicę do istniejącej tablicy i określasz typ danych.

Alternatywnie możesz użyć, removeAllktóry usuwa wszystkie elementy z tablicy i zapewnia opcję zachowania istniejącej pojemności.

existingArray.removeAll()

Jest to mutatingfunkcja, która oznacza, że ​​tablica wywołująca metodę zostanie zmieniona (pusta).


2

Kyle jest na dobrej drodze, ale jego kod zawiedzie, ponieważ możliwe indeksy zmniejszają się podczas wyliczania, co prowadzi do nielegalnych indeksów.

Jednym ze sposobów rozwiązania tego problemu jest wyliczanie wstecz. Robi się to szybko, używając kroków .

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

inną opcją byłoby użycie filter()

Swift 1.2

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

Szybki 2

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

Bardzo interesujące! Nie wiedziałem ostride
Kyle Decot

1

W języku Swift 2 dostępna jest metoda removeAllObjects ()

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

Aby usunąć element w określonym indeksie, użyj:

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

Aby usunąć ostatni element użyj:

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

Aby usunąć elementy z określonego zakresu użyj:

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

Aby usunąć określony element, użyj:

Syntax : public func removeObject(anObject: AnyObject)

Poniższy zrzut ekranu pokazuje listę metod dostępnych w rozszerzeniu NSMutableArray

Zrzut ekranu 1


0

Możesz też to zrobić:

for _ in myArray
{
    myArray.removeAtIndex(0)
}

2
To rozwiązanie jest strasznie nieefektywne - przy każdej iteracji przesuwane są wszystkie kolejne indeksy obiektów. Nie jestem też pewien, czy ta implementacja jest bezpieczna. Przynajmniej w kolekcjach Objective-C mutacja podczas wyliczania jest zabroniona.
Borys Verebskyi

0

Do usuwania wszystkich danych z tablicy

yourArrayData.removeAll()


0

Vadian ma poprawną odpowiedź dotyczącą tego, co próbujesz osiągnąć. Problem pokazany jako wynik przykładu kodu wynika ze sposobu, w jaki próbujesz utworzyć forpętlę. Indexrozpocznie się domyślnie od 0. Dodanie zakresu liczb po tym, jak nie jest poprawnym sposobem tworzenia pętli for. Dlatego widzisz błąd. Zamiast tego utwórz pętlę for w następujący sposób:

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

Mamy nadzieję, że ta odpowiedź pomoże innym, którzy są nowicjuszami w Swift lub programowaniu.


podczas iteracji kolekcji należy używać właściwości indeksów tablicy. Nie wszystkie kolekcje zaczynają się od indeksu zerowego
Leo Dabus

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.