web-dev-qa-db-fra.com

Supprimer un élément de tableau spécifique, égal à String - Swift

N'y a-t-il pas de moyen facile de supprimer un élément spécifique d'un tableau s'il est égal à une chaîne donnée? Les solutions de contournement consistent à rechercher l'index de l'élément du tableau que vous souhaitez supprimer, puis à removeAtIndex, ou à créer un nouveau tableau dans lequel vous ajoutez tous les éléments qui ne sont pas égaux à la chaîne donnée. Mais n'y a-t-il pas de moyen plus rapide?

52
TimWhiting

Vous pouvez utiliser filter () pour filtrer votre tableau comme suit

var strings = ["Hello","Playground","World"]

strings = strings.filter{$0 != "Hello"}

print(strings)   // "[Playground, World]"

éditer/mettre à jour:

Xcode 10 • Swift 4.2 ou version ultérieure

Vous pouvez utiliser la nouvelle méthode de mutation RangeReplaceableCollection appelée removeAll(where:)

var strings = ["Hello","Playground","World"]

strings.removeAll { $0 == "Hello" }

print(strings)   // "[Playground, World]"

Si vous avez besoin de supprimer uniquement la première occurrence d'un élément, nous pouvons implémenter une méthode de suppression personnalisée sur RangeReplaceableCollection pour contraindre les éléments à Équable:

extension RangeReplaceableCollection where Element: Equatable {
    @discardableResult
    mutating func removeFirstElementEqual(to element: Element) -> Element? {
        guard let index = firstIndex(of: element) else { return nil }
        return remove(at: index)
    }
}

Ou en utilisant un prédicat pour des éléments non-Equatable:

extension RangeReplaceableCollection {
    @discardableResult
    mutating func removeFirstElement(where predicate:  @escaping ((Element) -> Bool)) -> Element? {
        guard let index = firstIndex(where: predicate) else { return nil }
        return remove(at: index)
    }
}

var strings = ["Hello","Playground","World"]
strings.removeFirstElementEqual(to: "Hello")
print(strings)   // "[Playground, World]"
strings.removeFirstElement { $0 == "Playground" }
print(strings)   // "[World]"
126
Leo Dabus

Utiliser le filtre comme suggéré ci-dessus est agréable. Mais si vous voulez supprimer une seule occurrence d'une valeur ou si vous supposez qu'il n'y a pas de doublons dans le tableau et que vous voulez un algorithme plus rapide, utilisez ceci (dans Swift3):

if let index = array.index(of: "stringToRemove") {
    array.remove(at: index)
} else {
    // not found
}
9
Béatrice Cassistat

Il n'est pas clair si vous voulez dire plus rapidement en termes de temps d'exécution ou de quantité de code.

Dans ce dernier cas, vous pouvez facilement créer une copie en utilisant la méthode filter. Par exemple, étant donné le tableau suivant:

let array = ["1", "2", "3", "4", "5"]

vous pouvez créer une copie avec tous les éléments sauf "2" comme:

let filteredArray = array.filter { $0 != "2" }
9
Antonio

Vous voudrez utiliser filter(). Si vous avez un seul élément (appelé say obj) à supprimer, le prédicat filter() sera { $0 != obj }. Si vous faites cela à plusieurs reprises pour un grand tableau, cela peut être un problème de performances. Si vous pouvez différer la suppression d'objets individuels et que vous souhaitez supprimer un sous-tableau entier, utilisez l'une des options suivantes:

var stringsToRemove : [String] = ...
var strings : [String] = ...

strings.filter { !contains(stringsToRemove, $0) }

par exemple:

 1> ["a", "b", "c", "d"].filter { !contains(["b", "c"], $0) }
$R5: [String] = 2 values {
  [0] = "a"
  [1] = "d"
}
7
GoZoner

vous pouvez utiliser filter () en combinaison avec une surcharge de l'opérateur pour produire une solution facilement reproductible:

func -= (inout left: [String], right: String){
    left = left.filter{$0 != right}    
}

var myArrayOfStrings:[String] = ["Hello","Playground","World"]

myArrayOfStrings -= "Hello"

print(myArrayOfStrings)   // "[Playground, World]"
4
tukbuk23

si vous avez besoin de supprimer SubArray du tableau, alors c'est une solution parfaite en utilisant Swift:

var array = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"]            
let subArrayToDelete = ["c", "d", "e", "ee"]
array = array.filter{ !subArrayToDelete.contains($0) }
print(array) // ["a", "b", "f", "g", "h", "i", "j"]

c'est mieux pour votre performance que de supprimer un par un.

btw même plus rapide la solution est (mais il va réorganiser les éléments dans le tableau final):

array = Array(Set(array).subtracting(subArrayToDelete))
2
Tung Fam