Je veux énumérer un tableau dans Swift et supprimer certains éléments. Je me demande si cela est sans danger et, sinon, comment je suis censé y parvenir.
Actuellement, je ferais ceci:
for (index, aString: String) in enumerate(array) {
//Some of the strings...
array.removeAtIndex(index)
}
Dans Swift 2, ceci est assez facile avec enumerate
et reverse
.
var a = [1,2,3,4,5,6]
for (i,num) in a.enumerate().reverse() {
a.removeAtIndex(i)
}
print(a)
Voir mon swiftstub ici: http://swiftstub.com/944024718/?v=beta
Vous pourriez envisager la méthode filter
:
var theStrings = ["foo", "bar", "zxy"]
// Filter only strings that begins with "b"
theStrings = theStrings.filter { $0.hasPrefix("b") }
Le paramètre de filter
est simplement une fermeture qui prend une instance de type tableau (dans ce cas, String
) et retourne un Bool
. Lorsque le résultat est true
, l'élément est conservé, sinon l'élément est filtré.
Dans Swift 3 et 4, ce serait:
Avec des chiffres, selon la réponse de Johnston:
var a = [1,2,3,4,5,6]
for (i,num) in a.enumerated().reversed() {
a.remove(at: i)
}
print(a)
Avec chaînes comme question du PO:
var b = ["a", "b", "c", "d", "e", "f"]
for (i,str) in b.enumerated().reversed()
{
if str == "c"
{
b.remove(at: i)
}
}
print(b)
Cependant, maintenant dans Swift 4.2 ou version ultérieure, il existe un moyen encore meilleur et plus rapide qui avait été recommandé par Apple dans WWDC2018:
var c = ["a", "b", "c", "d", "e", "f"]
c.removeAll(where: {$0 == "c"})
print(c)
Cette nouvelle manière présente plusieurs avantages:
filter
.Lorsqu'un élément d'un certain index est supprimé d'un tableau, la position (et l'index) de tous les éléments suivants est modifiée, car ils reculent d'une position.
Le meilleur moyen est donc de naviguer dans le tableau dans l'ordre inverse - et dans ce cas, je suggère d'utiliser une boucle for traditionnelle:
for var index = array.count - 1; index >= 0; --index {
if condition {
array.removeAtIndex(index)
}
}
Cependant, à mon avis, la meilleure approche consiste à utiliser la méthode filter
, décrite par @perlfly dans sa réponse.
Non, il est dangereux de muter des tableaux pendant l'énumération, votre code va planter.
Si vous voulez supprimer seulement quelques objets, vous pouvez utiliser la fonction filter
.
Créez un tableau mutable pour stocker les éléments à supprimer puis, après l'énumération, supprimez ces éléments de l'original. Vous pouvez également créer une copie du tableau (immuable), l'énumérer et supprimer les objets (non par index) de l'original lors de l'énumération.
Je recommande de définir les éléments sur nil lors de l'énumération, puis de supprimer tous les éléments vides à l'aide de la méthode array () de array.