Très souvent, j'ai besoin de quelque chose comme ça:
CollectionUtils.RemoveAll(manager.getWindow().IconDisplay.Items, elem => elem.GetType() == typeof(ScatterViewItem));
4 Réponses :
Ceci est cuit directement dans la liste ou en C # 2.0: p> dans la liste des non-
static class CollectionUtils
{
public static void RemoveAll<T>(IList<T> list, Predicate<T> predicate)
{
int count = list.Count;
while (count-- > 0)
{
if (predicate(list[count])) list.RemoveAt(count);
}
}
public static void RemoveAll(IList list, Predicate<object> predicate)
{
int count = list.Count;
while (count-- > 0)
{
if (predicate(list[count])) list.RemoveAt(count);
}
}
}
Y a-t-il un moyen d'obtenir la même chose dans .NET 2.0?
@Matten - Ajout d'un exemple C # 2.0.
@MARC Gravell - Très simple, très élégant. Merci :)
@Matten - .NET 2.0 ou C # 2.0? .NET 2.0 prend en charge Linq qui fait partie de C # 3.0. CSHARPINDEPTH.COM/Articles/Chapter1/Versions.aspx
Juste pour être pédants - vous pouvez utiliser la version top (lambda) en C # 3.0 lors de la ciblage .NET 2.0; Les Lambdas sont (dans ce contexte, au moins) une fonctionnalité linguistique, pas une heure d'exécution.
@Omar - .net 2.0 ne officiellement i> Support Linq - mais il peut être piraté avec Linqbridge, etc ...
Vous pouvez également utiliser une boucle pour une boucle foreach. Ensuite, vous n'impliquez pas d'énumérateur en premier lieu.
@Omar - Nice à savoir. Mais nous sommes bloqués avec .NET 2.0 sans bibliothèques supplémentaires, donc c # 2.0 ... Peut-être que notre entreprise sera peut-être un jour mettant à jour les machines, mais ...
@Omar: Ne confondez pas les versions de cadre et d'exécution. LINQ faisait partie de .NET 3.5 (avec C # 3) qui fonctionne sur le même runtime que .NET 2.0.
@Marc - je vais l'essayer. Nous avons eu vs2010 il y a deux mois pour un projet SharePoint mais je ne l'ai pas utilisé pour nos anciens projets, pourtant
Et vous pouvez utiliser le compilateur C # 3.0 (ou ci-dessus) Compiler B> pour créer des applications exécutées sur .NET 2.0, via un ciblage multi-ciblage. Ensuite, vous obtenez des choses comme le support de Lambda, mais c'est toujours .net 2.0
@Marc une chose restante ... Devrais-je mettre les lignes de ligne.reMoveAll (ligne => ligne.fullFilScAnditions ()); dans la boucle de foresach?
@ROflCopTR - Dans l'exemple donné, non
@Marc Gravell mais alors qu'est-ce que la ligne référencée?
@ROFLCOPTR - LIGNE CODE> est le nom du paramètre d'une méthode anonyme que vous écrivez. DeleteLl fera la boucle en interne et pour chaque article i> Cela appellera cette méthode (dans ce contexte, elle pourrait également être appelée "prédicat"). Ainsi, sur les appels successifs de la méthode Anon, Line Code> contiendra l'élément de la liste que la méthode SuppleAll envisageait. Cela a-t-il du sens?
@MARC Gravell - Merci beaucoup, maintenant je comprends. Mais une dernière question. Et si ma collection n'implique pas RemoveAll ()? (J'ai aussi édité ma question pour cela)
Vous pouvez simplement remplacer la liste d'origine par filtré:
lines = lines.Where(line => line.FullfilsCertainConditions()).ToList();
Construire une nouvelle liste à la place:
public IList<Line> GetListWithoutFullfilsCertainConditions(IList<Line> fullList)
{
IList<Line> resultList = new List<Line>(fullList.Count);
foreach (Line line in fullList)
{
if (!line.FullfilsCertainConditions())
{
resultList.Add(line)
}
}
return resultList;
}
Aussi vous pouvez simplement utiliser en boucle.
int i = 0;
while(i < lines.Count)
{
if (lines[i].FullfilsCertainConditions())
{
lines.RemoveAt(i);
}
else {i++;}
}
J'ai eu le même problème il y a quelque temps et aucune solution. C'est encore pire - ce n'est pas 2n mais n ^ 2 depuis
lignes.remove (ligne) code> redevient sur la collection.Mais O (2n) est égal à O (n) :-) Vraiment: en Java, vous pouvez utiliser un itérateur pour le faire, ou aller pour une mise en œuvre de la collecte de copie-écriture qui permet des modifications tout en itération.
@Marc Gravell remercie beaucoup! Malheureusement, je ne peux pas uplifier une seconde fois!