Les méthodes Select
et Where
sont disponibles dans Linq. Que devraient savoir tous les développeurs de ces deux méthodes? Par exemple: quand utiliser l'un sur l'autre, les avantages de l'utilisation de l'un par rapport à l'autre, etc.Linq: Quelle est la différence entre Select et Où
Répondre
Où
trouve des éléments qui correspondent et ne retourne que ceux qui le font (filtrage).
->IEnumerable<A>
dans, IEnumerable<A>
sur
Sélectionnez
retours quelque chose pour tous les éléments de la source (projection/transformation). Ce quelque chose pourrait être les éléments eux-mêmes, mais sont plus généralement une projection de quelque sorte.
->IEnumerable<A>
dans, IEnumerable<B>
sur
'Select' retournera toujours le même nombre d'éléments dans la liste (indépendamment d'une condition de filtre que vous pourriez avoir). 'Where' peut renvoyer moins d'éléments en fonction de votre condition de filtre. –
Et [ici] (https://msdn.microsoft.com/en-us/library/bb548891 (v = vs.110) .aspx) est un exemple MSDN de 'select' et [ici] (https: // msdn.microsoft.com/en-us/library/bb534803(v=vs.110).aspx) est un pour 'where' – yazanpro
Au moins pour moi, ayant un peu de fond avec d'autres langues, il aide à penser que« Où == filter'' et '' Select == map'' – bgusach
Sélectionner les cartes d'une nouvelle structure. Si vous effectuez une sélection sur un IEnumerable, vous obtiendrez un tableau avec le même nombre d'éléments, mais un type différent en fonction du mappage spécifié. Où filtre IEnumerable pour qu'il vous donne un sous-ensemble de l'IEnumerable d'origine.
Ils sont distincts:
Select
est tout transformation.
Where
est tout sur filtrage.
Sélectionnez et Où sont deux opérateurs totalement différents agissant sur IEnumerable s.
Le premier est ce que nous appelons une projection opérateur, tandis que le dernier est un opérateur de restriction .
Une façon intéressante d'avoir un aperçu du comportement de tels opérateurs est de regarder leur "type fonctionnel".
Select: (IEnumerable < T1>, Func < T1, T2>) → IEnumerable < T2>; il prend en entrée à la fois un IEnumerable contenant des éléments de type T1 et une fonction transformant des éléments de type T1 en éléments de type T2. La sortie est un IEnumerable contenant des éléments de type T2. À partir de là, on peut facilement deviner que cet opérateur produira sa sortie en appliquant la fonction d'entrée sur chaque élément de l'entrée IEnumerable, et en enveloppant les résultats dans un nouvel IEnumerable. En utilisant une notation mathématique, il prend comme entrée (a, b, c, ...)): IEnumerable < T1> et f: T1 T2 → et produit (f (a), f (b), f (c), ...): IEnumerable < T2>
Où: (IEnumerable < T1>, Func < Tl, bool>) → IEnumerable T1>; celui-ci prend un IEnumerable contenant des éléments de type T1 et un prédicat sur T1 (c'est-à-dire une fonction qui produit un résultat booléen pour une entrée de type T1). Vous voyez que la sortie est aussi un IEnumerable contenant des éléments de type T1.
Cette fois, on devinerait qu'un élément de l'entrée IEnumerable sera présent sur la sortie IEnumerable en fonction du résultat de l'application du prédicat à l'élément. Ajoutant à cela la sémantique du nom de l'opérateur, vous pouvez être sûr qu'il produira la sortie IEnumerable en ne prenant à partir de l'entrée que les éléments qui ont la valeur true sur l'application du prédicat.
personnes programmation fonctionnelle fond pensent généralement comme ça. Cela vous permet de déduire (ou du moins de deviner ...) ce qu'un opérateur ne fait qu'en regardant son type! A titre d'exercice, essayez d'examiner les autres opérateurs introduits par LINQ sur IEnumerables et déduisez leur comportement, avant de regarder la documentation!
Si vous savez comment ils ont implémenté Où et sélectionnez les méthodes d'extension, vous pouvez prédire ce qu'il fait ... J'ai essayé d'implémenter où et sélectionnez les méthodes d'extension ... Vous pouvez jeter un coup d'œil ...
:: Où mise en œuvre
public static IEnumerable<Tsource> Where<Tsource> (this IEnumerable<Tsource> a , Func<Tsource , bool> Method)
{
foreach (var data in a)
{
//If the lambda Expression(delegate) returns "true" Then return the Data. (use 'yield' for deferred return)
if (Method.Invoke (data))
{
yield return data;
}
}
}
Sélectionner l'implémentation ::
public static IEnumerable<TResult> Select<TSource , TResult> (this IEnumerable<TSource> a , Func<TSource , TResult> Method)
{
foreach (var item in a)
{
//Each iteration call the delegate and return the Data back.(use 'yield' for deferred return)
yield return Method.Invoke (item);
}
}
Mon application fonctionne très bien pour toute collection .. Mais il diffère des méthodes d'extension implémentées par Microsoft, car elles utilisent des arborescences d'expression pour les implémenter.
Je ne pense pas que cette question devrait être marquée comme CW, il pourrait éventuellement avoir une réponse définitive. – Brandon
@Brandon il n'y a rien de mal à marquer quelque chose CW si c'est objectif. –
@Rex, je suis d'accord. Il suffit de dire que la différence entre Select et Where a une réponse définitive, et la deuxième partie de la question serait probablement basée sur des pratiques communément acceptées. Je le signalais juste au cas où l'OP n'était pas sûr de marquer les choses comme CW. S'il avait l'intention que ce soit CW, alors ça me va. – Brandon