web-dev-qa-db-fra.com

Comment supprimer un élément d'un tableau dans Swift

Comment puis-je supprimer/supprimer un élément d'un tableau dans le nouveau langage Apple d'Apple, Swift?

Voici un code:

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

Comment l'élément animals[2] peut-il être supprimé du tableau?

191
Leopold Joy

Le mot clé let sert à déclarer des constantes qui ne peuvent pas être modifiées. Si vous souhaitez modifier une variable, utilisez plutôt var, par exemple:

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

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

Une alternative non mutante qui conservera la collection d'origine inchangée consiste à utiliser filter pour créer une nouvelle collection sans les éléments à supprimer, par exemple:

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

Donné

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

Supprimer le premier élément

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

Supprimer le dernier élément

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

Supprimer l'élément à l'index

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

Supprimer un élément d'index inconnu

Pour un seul élément

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

Pour plusieurs éléments

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

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

Ou bien

animals.index(of: "chimps").map { animals.remove(at: $0) }

Remarques

  • Les méthodes ci-dessus modifient le tableau en place (à l'exception de filter) et renvoient l'élément supprimé.
  • Guide rapide pour réduire le filtre cartographique
  • Si vous ne souhaitez pas modifier le tableau d'origine, vous pouvez utiliser dropFirst ou dropLast pour créer un nouveau tableau.

Mis à jour en Swift 3

159
Suragch

Les réponses ci-dessus semblent présumer que vous connaissez l'index de l'élément que vous souhaitez supprimer.

Vous connaissez souvent la référence à l'objet que vous souhaitez supprimer du tableau. (Vous avez itéré dans votre tableau et l'avez trouvé, par exemple.) Dans de tels cas, il pourrait être plus facile de travailler directement avec la référence de l'objet sans devoir également passer partout son index. Par conséquent, je suggère cette solution. Il utilise le opérateur d'identité!==, que vous utilisez pour vérifier si deux références d'objet se rapportent toutes deux à la même instance d'objet.

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

Bien sûr, cela ne fonctionne pas uniquement pour Strings.

152
Daniel

Swift 4: Voici une extension simple et sympa pour supprimer des éléments d'un tableau, sans filtrage:

   extension Array where Element: Equatable {

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

}

Utilisation:

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

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

Fonctionne également avec d'autres types, tels que Int puisque Element est un type générique:

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

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

Pour Swift4:

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

Tu pourrais faire ça. Assurez-vous d'abord que Dog existe vraiment dans le tableau, puis supprimez-le. Ajoutez l'instruction for si vous pensez que Dog peut se produire plusieurs fois sur votre tableau.

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

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

Si vous êtes sûr que Dog quitte dans le tableau et ne s'est produit qu'une seule fois, faites simplement ça:

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

Si vous avez les deux, des chaînes et des nombres

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

Peu d'opération concerne Array à Swift

Créer un tableau

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

Ajouter un objet dans un tableau

stringArray = stringArray + ["Five"]

Obtenir la valeur de l'objet Index

let x = stringArray[1]

Ajouter un objet

stringArray.append("At last position")

Insérer un objet à l'index

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

Supprimer un objet

stringArray.removeAtIndex(3)

Concat Object value

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

À partir de Xcode 10+, et conformément au session 223 du WWDC 2018, "Embracing Algorithms" , une bonne méthode sera mutating func removeAll(where predicate: (Element) throws -> Bool) rethrows

Exemple d'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."

voir Documentation Apple

Ainsi, dans l'exemple du PO, supprimant les animaux [2], "chimpanzés":

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

Cette méthode peut être préférée car elle s'adapte bien (linéaire vs quadratique), est lisible et propre. Gardez à l'esprit que cela ne fonctionne que dans Xcode 10+, et en date de l'écriture, c'est en version bêta.

10
davidrynn

Si vous ne connaissez pas l'index de l'élément que vous souhaitez supprimer et que l'élément est conforme au protocole Equatable, vous pouvez procéder comme suit:

animals.removeAtIndex(animals.indexOf("dogs")!)

Voir la réponse de protocole Equatable: Comment faire indexOfObject ou un objet contient proprementObject

9
Byron

Supprimer des éléments en utilisant le tableau d'index:

  1. Tableau de chaînes et d'index

    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. Tableau d'entiers et d'index

    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]
    



Supprimer des éléments en utilisant la valeur d'un autre tablea

  1. Tableaux d'entiers

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

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

En ce qui concerne l'alternative @ Suragch à "Supprimer l'élément d'index inconnu":

Il existe une version plus puissante de "indexOf (élément)" qui correspond à un prédicat au lieu de l'objet lui-même. Il porte le même nom mais il a été appelé par myObjects.indexOf {$ 0.property = valueToMatch}. Il retourne l'index du premier élément correspondant trouvé dans le tableau myObjects.

Si l'élément est un objet/une structure, vous pouvez supprimer cet élément en fonction de la valeur de l'une de ses propriétés. Par exemple, vous avez une classe Car ayant la propriété car.color et vous voulez supprimer la voiture "rouge" de votre carsArray.

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

De manière prévisible, vous pouvez retravailler ceci pour supprimer "toutes" les voitures rouges en incorporant l'instruction if précédente dans une boucle repeat/while, et en attachant un bloc else pour définir un drapeau afin de "sortir" de la boucle.

5
ObjectiveTC

Je suis arrivé avec l'extension suivante qui s'occupe de supprimer des éléments d'un Array, en supposant que les éléments du Array Implement 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)
  }

}

Usage:

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

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

Si vous avez un tableau d'objets personnalisés, vous pouvez rechercher par propriété spécifique comme ceci:

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

ou si vous voulez chercher par nom par exemple

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

Cela devrait le faire (non testé):

animals[2..3] = []

Edit: et vous devez en faire une var, pas un let, sinon c'est une constante immuable.

2
Analog File

J'utilise cette extension, presque identique à celle de Varun, mais celle-ci (ci-dessous) est polyvalente:

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

extension pour supprimer l'objet String

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