Existe-t-il un moyen de supprimer tous les éléments sauf le premier de tout type de collection (Control.Items, List ....) en utilisant uniquement LINQ ?
Réponses
Trop de publicités?Non. LINQ est conçu pour interroger des collections (sans effets secondaires), pas pour ajouter ou supprimer des éléments.
Ce que vous pouvez faire, c'est écrire une requête qui prend le premier élément de la collection :
var result = source.Take(1);
Notez que LINQ ne fonctionne pas avec tous les types de collections ; vous avez besoin d'un fournisseur LINQ pour que LINQ fonctionne. Par exemple, source
doit implémenter IEnumerable<T> pour utiliser les méthodes d'extension de l'élément Classe énumérable (LINQ-to-Objects).
Que diriez-vous de quelque chose utilisant la réflexion ?
static void RemoveButFirst(object o){
Type t = o.GetType();
System.Reflection.MethodInfo rm = t.GetMethod("RemoveAt",
new Type[]{typeof(int)});
System.Reflection.PropertyInfo count = t.GetProperty("Count");
for (int n = (int)(count.GetValue(o,null)) ; n>1; n--)
rm.Invoke(o, new object[]{n-1});
}
Cela fonctionnerait chaque fois que votre collection expose un int Count
et une RemoveAt(int)
ce que je pense que ces collections devraient faire.
Et une version plus concise, utilisant dynamic
si vous travaillez avec C# 4.0 :
public static void RemoveBut(dynamic col, int k){
for (int n = col.Count; n>k; n--)
col.RemoveAt(n-1);
}
Vous pouvez utiliser .Take(1)
mais il renvoie une nouvelle collection, et laisse l'original intact.
L'idée de LINQ vient de la programmation fonctionnelle où tout est immuable, à cause de cela, ils n'ont pas rendu possible la modification des collections avec LINQ.
Jon Skeet a un commentaire sur le sujet : Équivalent LINQ de foreach pour IEnumerable<T>
- Réponses précédentes
- Plus de réponses