Come rimuovere un elemento da un array in Swift


236

Come posso annullare / rimuovere un elemento da un array nella nuova lingua di Swift di Apple?

Ecco un po 'di codice:

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

Come è possibile animals[2]rimuovere l'elemento dall'array?

Risposte:


300

La letparola chiave è per dichiarare costanti che non possono essere modificate. Se si desidera modificare una variabile, è necessario utilizzare varinvece, ad esempio:

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

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

Un'alternativa non mutante che manterrà invariata la raccolta originale è quella filterdi creare una nuova raccolta senza gli elementi che si desidera rimuovere, ad esempio:

let pets = animals.filter { $0 != "chimps" }

7
Cordiali saluti: removerestituisce l'elemento rimosso:let animal = animals.remove(at: 2)
2,

1
possiamo filtrare solo in base all'indice ??
Shaqir saiyed

@shaqirsaiyed Puoi filtrare qualsiasi predicato a cui puoi pensare. ad es. potresti filtrare tutti gli animali che terminano con una "s".
Womble,

aggiungi animali = animali domestici
Puji Wahono il

197

Dato

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

Rimuovi il primo elemento

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

Rimuovi l'ultimo elemento

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

Rimuovi elemento all'indice

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

Rimuovi elemento di indice sconosciuto

Per un solo elemento

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

Per più elementi

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

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

Appunti

  • I metodi precedenti modificano l'array in posizione (tranne per filter) e restituiscono l'elemento che è stato rimosso.
  • Guida rapida al filtro mappe Riduci
  • Se non si desidera modificare l'array originale, è possibile utilizzare dropFirsto dropLastcreare un nuovo array.

Aggiornato a Swift 5.2


Grazie per questi esempi, in te Rimuovi elemento di indice sconosciuto > per più elementi , quale chiusura scriveresti per rimuovere chimps && moose? Sto cercando qualcosa di diverso da{$0 != "chimps" && $0 != "moose"}

161

Le risposte di cui sopra sembrano presumere di conoscere l'indice dell'elemento che si desidera eliminare.

Spesso si conosce il riferimento all'oggetto che si desidera eliminare nella matrice. (Hai ripetuto il tuo array e l'hai trovato, ad es.) In questi casi potrebbe essere più semplice lavorare direttamente con il riferimento all'oggetto senza dover passare ovunque il suo indice. Quindi, suggerisco questa soluzione. Utilizza l' operatore di identità !== , che viene utilizzato per verificare se due riferimenti a oggetti si riferiscono entrambi alla stessa istanza di oggetto.

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

Naturalmente questo non funziona solo per Strings.


23
Dovrebbe esserelist = list.filter({ $0 != element })
Craig Grummitt il

5
Non se si desidera verificare con l'operatore di identità.
Daniel,

3
array.indexOf({ $0 == obj })
jrc,

2
Nota se altri oggetti fanno riferimento a listquesta eliminazione non aggiornerà gli altri riferimenti di array poiché stai assegnando un nuovo array a list. Un'implicazione sottile se si elimina dagli array con questo approccio.
Crashalot,

1
Il paradigma di programmazione funzionale si basa su oggetti immutabili. Cioè, non li cambi. Invece, si crea un nuovo oggetto. Questo è ciò che fa cancellare, mappare, ridurre, ecc. l'elenco sarà un oggetto appena creato. Nel frammento di codice sopra riportato mi sto assegnando di nuovo per elencare un oggetto appena creato. Questo funziona per me, perché progetto il mio codice in un modo che segue la programmazione funzionale.
Daniel,

44

Swift 5: ecco un'estensione semplice e intuitiva per rimuovere elementi in un array, senza filtrare:

   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)
    }

}

Utilizzo:

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

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

Funziona anche con altri tipi, come ad esempio Intpoiché Elementè un tipo generico:

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

myArray.remove(object: objectToRemove) // [4, 8, 6, 2]

1
Interessante questa matrice in cui Element: Equatable part
Nicolas Manzini,

1
Brillante. Anche se non funziona se si inizia con un elenco di protocolli, poiché - Il tipo di protocollo non può essere conforme a "Equatable" perché solo i tipi concreti possono essere conformi ai protocolli :-(
AW101

22

Per Swift4:

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

15

A partire da Xcode 10+, e secondo la sessione 223 del WWDC 2018, "Abbracciare algoritmi", un buon metodo per andare avanti saràmutating func removeAll(where predicate: (Element) throws -> Bool) rethrows

Esempio di Apple:

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."

vedere la documentazione di Apple

Quindi, nell'esempio del PO, rimuovere animali [2], "scimpanzé":

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

Questo metodo può essere preferito perché si adatta bene (lineare vs quadratico), è leggibile e pulito. Tieni presente che funziona solo in Xcode 10+ e al momento della scrittura questo è in beta.


removeAll (dove :) sarà in grado solo in rapido 4.2
Vlad Pulichev

14

Poche operazioni si riferiscono all'array in Swift

Crea array

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

Aggiungi oggetto nell'array

stringArray = stringArray + ["Five"]

Ottieni valore dall'oggetto Index

let x = stringArray[1]

Aggiungi oggetto

stringArray.append("At last position")

Inserisci oggetto nell'indice

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

Rimuovi oggetto

stringArray.removeAtIndex(3)

Valore dell'oggetto Concat

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

14

Potresti farlo. Prima assicurati Dogche esista davvero nell'array, quindi rimuovilo. Aggiungi la fordichiarazione se ritieni che Dogpossa accadere più di una volta sul tuo array.

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

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

Se sei sicuro di Doguscire dall'array e che è successo solo una volta, fallo semplicemente:

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

Se hai entrambi, stringhe e numeri

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)!)
        }
    }
}

Cosa succede se il mio array non contiene stringhe?
Apqu,

@apqu ha fatto un altro aggiornamento '|| object == Int () 'e' || object == String () 'non sono necessari
GuiSoySauce

il looping di un array aumenta l'efficienza. controlla .filter, .compactMap
MLBDG il


10

Rimuovere gli elementi utilizzando la matrice degli indici:

  1. Matrice di stringhe e indici

    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. Matrice di numeri interi e indici

    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]



Rimuovere gli elementi usando il valore dell'elemento di un altro array

  1. Matrici di numeri interi

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

    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"]

4
Questa è una risposta di copertina ed è molto efficiente per una migliore codifica ed esecuzione rapida.
iOSDev,

Ciao @Krunal - ottima risposta, potresti dare un'occhiata alla seguente domanda (rilasciando immagini da un array di immagini): stackoverflow.com/questions/47735975/…
Server Programmer

6

Per quanto riguarda l'alternativa di @ Suragch a "Rimuovi elemento di indice sconosciuto":

Esiste una versione più potente di "indexOf (element)" che corrisponderà a un predicato anziché all'oggetto stesso. Prende lo stesso nome ma è chiamato da myObjects.indexOf {$ 0.property = valueToMatch}. Restituisce l'indice del primo elemento corrispondente trovato nell'array myObjects.

Se l'elemento è un oggetto / struttura, è possibile rimuoverlo in base al valore di una delle sue proprietà. Ad esempio, hai una classe Car con proprietà car.color e vuoi rimuovere l'auto "rossa" dalle tue auto.

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

Prevedibilmente, potresti rielaborare questo per rimuovere "tutte" le macchine rosse incorporando la precedente istruzione if in un ciclo repeat / while e collegando un blocco else per impostare una bandiera per "spezzare" fuori dal ciclo.


6

Swift 5

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

4

Se disponi di una matrice di oggetti personalizzati, puoi cercare per proprietà specifica come questa:

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

o se si desidera cercare per nome, ad esempio

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

3

Questo dovrebbe farlo (non testato):

animals[2..3] = []

Modifica: e devi renderlo un var, non un let, altrimenti è una costante immutabile.


5
Quando si utilizza un (sotto) intervallo di un array esistente per creare un altro array, l'intervallo deve avere 3 punti. Quanto sopra dovrebbe essere scritto come animali [2 ... 3]
zevij

3

Mi è venuta in mente la seguente estensione che si occupa di rimuovere elementi da un Array, assumendo gli elementi Arraynell'attrezzo 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)
  }

}

Uso:

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

var test2 = [1, 2, 1, 2]
test2.removeFirstEqualItem(2) // [1, 1, 2]

Ciao @nburk - ottima risposta, potresti dare un'occhiata alla seguente domanda (rilasciando immagini da un array di immagini): stackoverflow.com/questions/47735975/…
Server Programmer

1

estensione per rimuovere l'oggetto String

extension Array {
    mutating func delete(element: String) {
        self = self.filter() { $0 as! String != element }
    }
}

forzare lo scartamento può causare un arresto, penso che dovresti evitarlo in questo caso.
user3206558

Che cos'è una funzione "mutante"?
AwesomeElephant8232

era solito dire che questa funzione cambierà il sé (array).
Varun Naharia,

1

Uso questa estensione, quasi uguale a quella di Varun, ma questa (sotto) è per tutti gli usi:

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

1

Per rimuovere elementi da un array, usare remove(at:), removeLast()e removeAll().

yourArray = [1,2,3,4]

Rimuovere il valore in 2 posizioni

yourArray.remove(at: 2)

Rimuovi l'ultimo valore dall'array

yourArray.removeLast()

Rimuove tutti i membri dal set

yourArray.removeAll()
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.