Je dois supprimer certaines lignes d'un tableau de données. J'ai entendu dire qu'il n'était pas acceptable de modifier une collection tout en la parcourant. Ainsi, au lieu d'utiliser une boucle for dans laquelle je vérifie si une ligne répond aux critères de suppression et la marque ensuite comme supprimée, je devrais d'abord itérer dans le tableau de données et ajouter toutes les lignes dans une liste, puis itérer dans la liste et marquer les lignes à supprimer. Quelles sont les raisons de ce choix et quelles sont les autres possibilités qui s'offrent à moi (au lieu d'utiliser la liste des lignes) ?
Réponses
Trop de publicités?L'itération à rebours dans la liste semble être une meilleure approche, car si vous supprimez un élément et que d'autres éléments "tombent dans le vide", cela n'a pas d'importance car vous les avez déjà examinés. De plus, vous n'avez pas à vous soucier du fait que votre variable de compteur devienne plus grande que le .Count.
List<int> test = new List<int>();
test.Add(1);
test.Add(2);
test.Add(3);
test.Add(4);
test.Add(5);
test.Add(6);
test.Add(7);
test.Add(8);
for (int i = test.Count-1; i > -1; i--)
{
if(someCondition){
test.RemoveAt(i);
}
}
En prenant le code de @bruno, je le ferais à l'envers.
En effet, lorsque vous reculez, les indices de tableau manquants n'interfèrent pas avec l'ordre de votre boucle.
var l = new List<int>(new int[] { 0, 1, 2, 3, 4, 5, 6 });
for (int i = l.Count - 1; i >= 0; i--)
if (l[i] % 2 == 0)
l.RemoveAt(i);
foreach (var i in l)
{
Console.WriteLine(i);
}
Mais sérieusement, de nos jours, j'utiliserais LINQ :
var l = new List<int>(new int[] { 0, 1, 2, 3, 4, 5, 6 });
l.RemoveAll(n => n % 2 == 0);
Vous pouvez supprimer des éléments d'une collection si vous utilisez une simple fonction for
boucle.
Regardez cet exemple :
var l = new List<int>();
l.Add(0);
l.Add(1);
l.Add(2);
l.Add(3);
l.Add(4);
l.Add(5);
l.Add(6);
for (int i = 0; i < l.Count; i++)
{
if (l[i] % 2 == 0)
{
l.RemoveAt(i);
i--;
}
}
foreach (var i in l)
{
Console.WriteLine(i);
}
Comme vous travaillez avec une DataTable et que vous devez être en mesure de faire persister les modifications sur le serveur à l'aide d'un adaptateur de table (voir les commentaires), voici un exemple de la façon dont vous devez supprimer des lignes :
DataTable dt;
// remove all rows where the last name starts with "B"
foreach (DataRow row in dt.Rows)
{
if (row["LASTNAME"].ToString().StartsWith("B"))
{
// mark the row for deletion:
row.Delete();
}
}
L'appel à la suppression des lignes changera leur propriété RowState en Deleted, mais laissera les lignes supprimées dans le tableau. Si vous avez encore besoin de travailler avec cette table avant de persister les changements vers le serveur (par exemple, si vous voulez afficher le contenu de la table sans les lignes supprimées), vous devez vérifier le RowState de chaque ligne pendant que vous l'itérez comme ceci :
foreach (DataRow row in dt.Rows)
{
if (row.RowState != DataRowState.Deleted)
{
// this row has not been deleted - go ahead and show it
}
}
Le retrait de lignes de la collection (comme dans la réponse de bruno) cassera l'adaptateur de table, et ne devrait généralement pas être fait avec une DataTable.