Je recherche un moyen très rapide de filtrer une collection en C #. J'utilise actuellement des collections génériques List <object>, mais je suis ouvert à l'utilisation d'autres structures si elles fonctionnent mieux.
Actuellement, je suis en train de créer une nouvelle liste <objet> et de parcourir la liste d'origine. Si les critères de filtrage correspondent, j'en mets une copie dans la nouvelle liste.
Y a-t-il une meilleure manière de faire cela? Existe-t-il un moyen de filtrer en place afin qu'aucune liste temporaire ne soit requise?
c#
collections
filtering
Jason Z
la source
la source
Réponses:
Si vous utilisez C # 3.0, vous pouvez utiliser linq, bien meilleur et bien plus élégant:
Si vous ne trouvez pas le
.Where
, cela signifie que vous devez importerusing System.Linq;
en haut de votre fichier.la source
.Where(predefinedQuery)
au lieu d'utiliser.Where(x => x > 7)
?public bool predefinedQuery(int x) { return x > 7; }
. Ensuite, votre.Where(predefinedQuery)
fonctionnerait très bien.Voici un bloc de code / exemple de filtrage de liste à l'aide de trois méthodes différentes que j'ai rassemblées pour afficher le filtrage de liste basé sur Lambdas et LINQ.
la source
List<T>
a uneFindAll
méthode qui effectuera le filtrage pour vous et retournera un sous-ensemble de la liste.MSDN a un excellent exemple de code ici: http://msdn.microsoft.com/en-us/library/aa701359(VS.80).aspx
EDIT: j'ai écrit ceci avant d'avoir une bonne compréhension de LINQ et du
Where()
méthode. Si je devais écrire ceci aujourd'hui, j'utiliserais probablement la méthode mentionnée par Jorge ci-dessus. LaFindAll
méthode fonctionne toujours si vous êtes bloqué dans un environnement .NET 2.0.la source
Vous pouvez utiliser IEnumerable pour éliminer le besoin d'une liste temporaire.
où Matches est le nom de votre méthode de filtrage. Et vous pouvez utiliser ceci comme:
Cela appellera la fonction GetFilteredItems en cas de besoin et dans certains cas où vous n'utilisez pas tous les éléments de la collection filtrée, cela peut fournir un bon gain de performances.
la source
Pour le faire sur place, vous pouvez utiliser la méthode RemoveAll de la classe "List <>" avec une classe "Predicate" personnalisée ... mais tout ce qui ne fait que nettoyer le code ... sous le capot, c'est la même chose chose que vous êtes ... mais oui, il le fait en place, donc vous faites la même chose avec la liste temporaire.
la source
Vous pouvez utiliser la méthode FindAll de la liste, en fournissant un délégué sur lequel filtrer. Cependant, je suis d'accord avec @ IainMH qu'il ne vaut pas la peine de trop s'inquiéter à moins que ce ne soit une liste énorme.
la source
Ou, si vous préférez, utilisez la syntaxe de requête spéciale fournie par le compilateur C # 3:
la source
L'utilisation de LINQ est relativement beaucoup plus lente que l'utilisation d'un prédicat fourni à la
FindAll
méthode Lists . Faites également attention avec LINQ car l'énumération delist
n'est pas réellement exécutée tant que vous n'avez pas accédé au résultat. Cela peut signifier que, lorsque vous pensez avoir créé une liste filtrée, le contenu peut différer de ce que vous attendiez lorsque vous la lisez réellement.la source
Si votre liste est très grande et que vous filtrez à plusieurs reprises, vous pouvez trier la liste d'origine sur l'attribut de filtre, effectuer une recherche binaire pour trouver les points de départ et d'arrivée.
Temps initial O (n * log (n)) puis O (log (n)).
Le filtrage standard prendra O (n) à chaque fois.
la source