So entfernen Sie ein Element aus einem Array in Swift

236

Wie kann ich ein Element in Apples neuer Sprache Swift aus einem Array entfernen / entfernen?

Hier ist ein Code:

let animals = ["cats", "dogs", "chimps", "moose"]

Wie könnte das Element animals[2]aus dem Array entfernt werden?

Leopold Joy
quelle

Antworten:

300

Das letSchlüsselwort dient zum Deklarieren von Konstanten, die nicht geändert werden können. Wenn Sie eine Variable ändern möchten, sollten Sie varstattdessen Folgendes verwenden: z.

var animals = ["cats", "dogs", "chimps", "moose"]

animals.remove(at: 2)  //["cats", "dogs", "moose"]

Eine nicht mutierende Alternative, die die ursprüngliche Sammlung unverändert lässt, besteht filterdarin, eine neue Sammlung zu erstellen, ohne dass die Elemente entfernt werden sollen, z.

let pets = animals.filter { $0 != "chimps" }
Mythos
quelle
7
Zu removelet animal = animals.remove(at: 2)
Ihrer Information
1
können wir nur nach Index filtern?
Shaqir sagte am
@shaqirsaiyed Sie können nach jedem Prädikat filtern, das Sie sich ausdenken können. Sie könnten beispielsweise alle Tiere herausfiltern, die mit einem "s" enden.
Womble
Tiere hinzufügen = Haustiere
Puji Wahono
197

Gegeben

var animals = ["cats", "dogs", "chimps", "moose"]

Entfernen Sie das erste Element

animals.removeFirst() // "cats"
print(animals)        // ["dogs", "chimps", "moose"]

Letztes Element entfernen

animals.removeLast() // "moose"
print(animals)       // ["cats", "dogs", "chimps"]

Element am Index entfernen

animals.remove(at: 2) // "chimps"
print(animals)           // ["cats", "dogs", "moose"]

Element mit unbekanntem Index entfernen

Für nur ein Element

if let index = animals.firstIndex(of: "chimps") {
    animals.remove(at: index)
}
print(animals) // ["cats", "dogs", "moose"]

Für mehrere Elemente

var animals = ["cats", "dogs", "chimps", "moose", "chimps"]

animals = animals.filter(){$0 != "chimps"}
print(animals) // ["cats", "dogs", "moose"]

Anmerkungen

  • Die obigen Methoden ändern das Array an Ort filterund Stelle (mit Ausnahme von ) und geben das entfernte Element zurück.
  • Schnelle Anleitung zum Reduzieren des Kartenfilters
  • Wenn Sie das ursprüngliche Array nicht ändern möchten, können Sie ein neues Array verwenden dropFirstoder dropLasterstellen.

Auf Swift 5.2 aktualisiert

Suragch
quelle
Vielen Dank für diese Beispiele in Sie entfernt Element unbekannten Index > für mehrere Elemente , welche Schließung würden Sie schreiben entfernen chimps && moosezum Beispiel? Ich suche etwas anderes als{$0 != "chimps" && $0 != "moose"}
161

Die obigen Antworten scheinen davon auszugehen, dass Sie den Index des Elements kennen, das Sie löschen möchten.

Oft kennen Sie den Verweis auf das Objekt, das Sie im Array löschen möchten. (Sie haben Ihr Array durchlaufen und es gefunden, z. B.) In solchen Fällen ist es möglicherweise einfacher, direkt mit der Objektreferenz zu arbeiten, ohne auch überall ihren Index übergeben zu müssen. Daher schlage ich diese Lösung vor. Es verwendet den Identitätsoperator !== , mit dem Sie testen, ob zwei Objektreferenzen auf dieselbe Objektinstanz verweisen.

func delete(element: String) {
    list = list.filter() { $0 !== element }
}

Natürlich funktioniert das nicht nur für Strings.

Daniel
quelle
23
Sollte seinlist = list.filter({ $0 != element })
Craig Grummitt
5
Nicht, wenn Sie sich beim Identitätsoperator erkundigen möchten.
Daniel
3
array.indexOf({ $0 == obj })
jrc
2
Wenn andere Objekte auf listdiese Löschung verweisen, werden die anderen Array-Referenzen nicht aktualisiert, da Sie ein neues Array zuweisen list. Nur eine subtile Implikation, wenn Sie mit diesem Ansatz aus Arrays löschen.
Crashalot
1
Das funktionale Programmierparadigma beruht auf unveränderlichen Objekten. Dh du änderst sie nicht. Stattdessen erstellen Sie ein neues Objekt. Dies ist, was Löschen, Zuordnen, Reduzieren usw. bewirkt. Liste wird ein neu erstelltes Objekt sein. Im obigen Codefragment weise ich zurück, um ein neu erstelltes Objekt aufzulisten. Das funktioniert bei mir, weil ich meinen Code so gestalte, dass er der funktionalen Programmierung folgt.
Daniel
44

Swift 5: Hier ist eine coole und einfache Erweiterung zum Entfernen von Elementen in einem Array ohne Filterung:

   extension Array where Element: Equatable {

    // Remove first collection element that is equal to the given `object`:
    mutating func remove(object: Element) {
        guard let index = firstIndex(of: object) else {return}
        remove(at: index)
    }

}

Verwendung :

var myArray = ["cat", "barbecue", "pancake", "frog"]
let objectToRemove = "cat"

myArray.remove(object: objectToRemove) // ["barbecue", "pancake", "frog"]

Funktioniert auch mit anderen Typen, z. B. Intda Elementes sich um einen generischen Typ handelt:

var myArray = [4, 8, 17, 6, 2]
let objectToRemove = 17

myArray.remove(object: objectToRemove) // [4, 8, 6, 2]
Skaal
quelle
1
Interessant dieses Array, wo Element: Gleichwertiger Teil
Nicolas Manzini
1
Brillant. Obwohl es nicht funktioniert, wenn Sie mit einer Liste von Protokollen beginnen, kann der Protokolltyp nicht mit 'Equatable' übereinstimmen, da nur konkrete Typen den Protokollen entsprechen können :-(
AW101
22

Für Swift4:

list = list.filter{$0 != "your Value"}

quelle
15

Ab Xcode 10+ und gemäß der WWDC 2018-Sitzung 223, "Embracing Algorithms", wird eine gute Methode für die Zukunft seinmutating func removeAll(where predicate: (Element) throws -> Bool) rethrows

Apples Beispiel:

var phrase = "The rain in Spain stays mainly in the plain."
let vowels: Set<Character> = ["a", "e", "i", "o", "u"]

phrase.removeAll(where: { vowels.contains($0) })
// phrase == "Th rn n Spn stys mnly n th pln."

Siehe Apples Dokumentation

Im Beispiel des OP: Entfernen von Tieren [2], "Schimpansen":

var animals = ["cats", "dogs", "chimps", "moose"]
animals.removeAll(where: { $0 == "chimps" } )
// or animals.removeAll { $0 == "chimps" }

Diese Methode kann bevorzugt werden, da sie gut skaliert (linear oder quadratisch), lesbar und sauber ist. Denken Sie daran, dass es nur in Xcode 10+ funktioniert und zum Zeitpunkt des Schreibens in der Beta.

Davidrynn
quelle
removeAll (wo :) wird nur in der schnellen 4.2
Vlad Pulichev
14

Nur wenige Operationen beziehen sich auf das Array in Swift

Array erstellen

var stringArray = ["One", "Two", "Three", "Four"]

Objekt im Array hinzufügen

stringArray = stringArray + ["Five"]

Wert vom Indexobjekt abrufen

let x = stringArray[1]

Objekt anhängen

stringArray.append("At last position")

Objekt am Index einfügen

stringArray.insert("Going", atIndex: 1)

Objekt entfernen

stringArray.removeAtIndex(3)

Concat-Objektwert

var string = "Concate Two object of Array \(stringArray[1]) + \(stringArray[2])"
Solide weich
quelle
14

Das könntest du machen. Stellen Sie zuerst sicher, dass Dogdas Array wirklich vorhanden ist, und entfernen Sie es dann. Fügen Sie die forAnweisung hinzu, wenn Sie glauben Dog, dass sie in Ihrem Array mehrmals vorkommt.

var animals = ["Dog", "Cat", "Mouse", "Dog"]
let animalToRemove = "Dog"

for object in animals
{
    if object == animalToRemove{
        animals.removeAtIndex(animals.indexOf(animalToRemove)!)
    }
}

Wenn Sie sicher sind, dass Dogdas Array beendet wird und nur einmal passiert ist, tun Sie Folgendes:

animals.removeAtIndex(animals.indexOf(animalToRemove)!)

Wenn Sie beide haben, Zeichenfolgen und Zahlen

var array = [12, 23, "Dog", 78, 23]
let numberToRemove = 23
let animalToRemove = "Dog"

for object in array
{

    if object is Int
    {
        // this will deal with integer. You can change to Float, Bool, etc...
        if object == numberToRemove
        {
        array.removeAtIndex(array.indexOf(numberToRemove)!)
        }
    }
    if object is String
    {
        // this will deal with strings
        if object == animalToRemove
        {
        array.removeAtIndex(array.indexOf(animalToRemove)!)
        }
    }
}
GuiSoySauce
quelle
Was ist, wenn mein Array keine Strings enthält?
Apqu
@apqu hat ein weiteres Update durchgeführt '|| object == Int () 'und' || object == String () 'sind nicht
erforderlich
Das Schleifen eines Arrays wirkt sich negativ auf die Effizienz aus. Überprüfen Sie .filter, .compactMap
MLBDG
10

Entfernen Sie Elemente mithilfe des Indexarrays:

  1. Array von Zeichenfolgen und Indizes

    let animals = ["cats", "dogs", "chimps", "moose", "squarrel", "cow"]
    let indexAnimals = [0, 3, 4]
    let arrayRemainingAnimals = animals
        .enumerated()
        .filter { !indexAnimals.contains($0.offset) }
        .map { $0.element }
    
    print(arrayRemainingAnimals)
    
    //result - ["dogs", "chimps", "cow"]
  2. Array von Ganzzahlen und Indizes

    var numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
    let indexesToRemove = [3, 5, 8, 12]
    
    numbers = numbers
        .enumerated()
        .filter { !indexesToRemove.contains($0.offset) }
        .map { $0.element }
    
    print(numbers)
    
    //result - [0, 1, 2, 4, 6, 7, 9, 10, 11]



Entfernen Sie Elemente mit dem Elementwert eines anderen Arrays

  1. Arrays von ganzen Zahlen

    let arrayResult = numbers.filter { element in
        return !indexesToRemove.contains(element)
    }
    print(arrayResult)
    
    //result - [0, 1, 2, 4, 6, 7, 9, 10, 11]
  2. Arrays von Strings

    let arrayLetters = ["a", "b", "c", "d", "e", "f", "g", "h", "i"]
    let arrayRemoveLetters = ["a", "e", "g", "h"]
    let arrayRemainingLetters = arrayLetters.filter {
        !arrayRemoveLetters.contains($0)
    }
    
    print(arrayRemainingLetters)
    
    //result - ["b", "c", "d", "f", "i"]
Krunal
quelle
4
Dies ist eine Einzeiler-Antwort und für eine bessere Codierung und schnelle Ausführung sehr effizient.
Der iOSDev
Hallo @Krunal - tolle Antwort, könnten Sie sich die folgende Frage ansehen (Bilder aus einem Bildarray
Server Programmer
6

In Bezug auf @ Suragchs Alternative zu "Element eines unbekannten Index entfernen":

Es gibt eine leistungsfähigere Version von "indexOf (Element)", die mit einem Prädikat anstelle des Objekts selbst übereinstimmt. Es hat den gleichen Namen, wird aber von myObjects.indexOf {$ 0.property = valueToMatch} aufgerufen. Es gibt den Index des ersten übereinstimmenden Elements zurück, das im myObjects-Array gefunden wurde.

Wenn das Element ein Objekt / eine Struktur ist, möchten Sie dieses Element möglicherweise basierend auf einem Wert einer seiner Eigenschaften entfernen. Sie haben beispielsweise eine Autoklasse mit der Eigenschaft car.color und möchten das "rote" Auto aus Ihrem Autos entfernen.

if let validIndex = (carsArray.indexOf{$0.color == UIColor.redColor()}) {
  carsArray.removeAtIndex(validIndex)
}

Voraussichtlich können Sie dies überarbeiten, um "alle" roten Autos zu entfernen, indem Sie die obige if-Anweisung in eine Wiederholungs- / while-Schleife einbetten und einen else-Block anhängen, um ein Flag zu setzen, das aus der Schleife "ausbricht".

ObjectiveTC
quelle
6

Swift 5

guard let index = orders.firstIndex(of: videoID) else { return }
orders.remove(at: index)
Hieronymus
quelle
4

Wenn Sie über ein Array von benutzerdefinierten Objekten verfügen, können Sie nach bestimmten Eigenschaften wie folgt suchen:

    if let index = doctorsInArea.indexOf({$0.id == doctor.id}){
        doctorsInArea.removeAtIndex(index)
    }

oder wenn Sie zum Beispiel nach Namen suchen möchten

    if let index = doctorsInArea.indexOf({$0.name == doctor.name}){
        doctorsInArea.removeAtIndex(index)
    }
Abo3atef
quelle
3

Dies sollte es tun (nicht getestet):

animals[2..3] = []

Bearbeiten: und Sie müssen es zu einem machen var, nicht zu einem let, sonst ist es eine unveränderliche Konstante.

Analoge Datei
quelle
5
Wenn Sie einen (Unter-) Bereich eines vorhandenen Arrays verwenden, um ein anderes Array zu erstellen, muss der Bereich 3 Punkte haben. Das obige sollte als Tiere [2 ... 3] geschrieben werden
zevij
3

Ich habe die folgende Erweiterung entwickelt, die sich um das Entfernen von Elementen aus einem kümmert Array, vorausgesetzt, die Elemente im ArrayGerät Equatable:

extension Array where Element: Equatable {

  mutating func removeEqualItems(item: Element) {
    self = self.filter { (currentItem: Element) -> Bool in
      return currentItem != item
    }
  }

  mutating func removeFirstEqualItem(item: Element) {
    guard var currentItem = self.first else { return }
    var index = 0
    while currentItem != item {
      index += 1
      currentItem = self[index]
    }
    self.removeAtIndex(index)
  }

}

Verwendung:

var test1 = [1, 2, 1, 2]
test1.removeEqualItems(2) // [1, 1]

var test2 = [1, 2, 1, 2]
test2.removeFirstEqualItem(2) // [1, 1, 2]
nburk
quelle
Hallo @nburk - tolle Antwort, könnten Sie sich die folgende Frage ansehen (Bilder aus einem Bildarray
Server Programmer
1

Erweiterung zum Entfernen des String-Objekts

extension Array {
    mutating func delete(element: String) {
        self = self.filter() { $0 as! String != element }
    }
}
Varun Naharia
quelle
Das gewaltsame Auspacken kann zu einem Absturz führen. Ich denke, Sie sollten dies in diesem Fall vermeiden.
user3206558
Was ist eine "mutierende" Funktion?
AwesomeElephant8232
Früher wurde gesagt, dass diese Funktion das Selbst (Array) verändert.
Varun Naharia
1

Ich benutze diese Erweiterung, fast die gleiche wie die von Varun, aber diese (unten) ist universell einsetzbar:

 extension Array where Element: Equatable  {
        mutating func delete(element: Iterator.Element) {
                self = self.filter{$0 != element }
        }
    }
user3206558
quelle
1

Zum Entfernen von Elementen aus einem Array, verwenden remove(at:), removeLast()und removeAll().

yourArray = [1,2,3,4]

Entfernen Sie den Wert an Position 2

yourArray.remove(at: 2)

Entfernen Sie den letzten Wert aus dem Array

yourArray.removeLast()

Entfernt alle Mitglieder aus dem Set

yourArray.removeAll()
PatelFab
quelle