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?
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:
La let
parola chiave è per dichiarare costanti che non possono essere modificate. Se si desidera modificare una variabile, è necessario utilizzare var
invece, 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 filter
di creare una nuova raccolta senza gli elementi che si desidera rimuovere, ad esempio:
let pets = animals.filter { $0 != "chimps" }
Dato
var animals = ["cats", "dogs", "chimps", "moose"]
animals.removeFirst() // "cats"
print(animals) // ["dogs", "chimps", "moose"]
animals.removeLast() // "moose"
print(animals) // ["cats", "dogs", "chimps"]
animals.remove(at: 2) // "chimps"
print(animals) // ["cats", "dogs", "moose"]
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"]
filter
) e restituiscono l'elemento che è stato rimosso.dropFirst
o dropLast
creare un nuovo array.Aggiornato a Swift 5.2
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 String
s.
list = list.filter({ $0 != element })
array.indexOf({ $0 == obj })
list
questa 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.
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 Int
poiché Element
è un tipo generico:
var myArray = [4, 8, 17, 6, 2]
let objectToRemove = 17
myArray.remove(object: objectToRemove) // [4, 8, 6, 2]
Per Swift4:
list = list.filter{$0 != "your Value"}
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.
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])"
Potresti farlo. Prima assicurati Dog
che esista davvero nell'array, quindi rimuovilo. Aggiungi la for
dichiarazione se ritieni che Dog
possa 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 Dog
uscire 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)!)
}
}
}
Se non si conosce l'indice dell'elemento che si desidera rimuovere e l'elemento è conforme al protocollo Equatable, è possibile eseguire:
animals.removeAtIndex(animals.indexOf("dogs")!)
Vedi la risposta del protocollo equabile: Come posso fare indexOfObject o un vero oggetto contiene
Rimuovere gli elementi utilizzando la matrice degli indici:
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"]
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
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]
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"]
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.
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)
}
Questo dovrebbe farlo (non testato):
animals[2..3] = []
Modifica: e devi renderlo un var
, non un let
, altrimenti è una costante immutabile.
Mi è venuta in mente la seguente estensione che si occupa di rimuovere elementi da un Array
, assumendo gli elementi Array
nell'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)
}
}
var test1 = [1, 2, 1, 2]
test1.removeEqualItems(2) // [1, 1]
var test2 = [1, 2, 1, 2]
test2.removeFirstEqualItem(2) // [1, 1, 2]
estensione per rimuovere l'oggetto String
extension Array {
mutating func delete(element: String) {
self = self.filter() { $0 as! String != element }
}
}
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 }
}
}
remove
restituisce l'elemento rimosso:let animal = animals.remove(at: 2)