web-dev-qa-db-fra.com

Intersection de la requête LINQ

Si j'ai un IEnumerable où ClassA expose une propriété ID de type long. Est-il possible d'utiliser une requête Linq pour obtenir toutes les instances de ClassA avec l'ID appartenant à un deuxième IEnumerable?

En d'autres termes, cela peut-il être fait?

IEnumerable<ClassA> = original.Intersect(idsToFind....)?

où l'original est un IEnumerable<ClassA> et idsToFind est IEnumerable<long>.

48
Klaus Nji

Oui.

Comme d'autres personnes l'ont répondu, vous pouvez utiliser Where, mais il sera extrêmement inefficace pour les grands ensembles.

Si les performances sont un problème, vous pouvez appeler Join :

var results = original.Join(idsToFind, o => o.Id, id => id, (o, id) => o);

Si idsToFind peut contenir des doublons, vous devrez soit appeler Distinct() sur les ID ou sur les résultats, soit remplacer Join par GroupJoin (Les paramètres de GroupJoin seraient les mêmes).

56
SLaks

Je posterai une réponse en utilisant Intersect.

Ceci est utile si vous souhaitez croiser 2 IEnumerables du même type.

Nous aurons d'abord besoin d'un EqualityComparer:

    public class KeyEqualityComparer<T> : IEqualityComparer<T>
    {
        private readonly Func<T, object> keyExtractor;

        public KeyEqualityComparer(Func<T, object> keyExtractor)
        {
            this.keyExtractor = keyExtractor;
        }

        public bool Equals(T x, T y)
        {
            return this.keyExtractor(x).Equals(this.keyExtractor(y));
        }

        public int GetHashCode(T obj)
        {
            return this.keyExtractor(obj).GetHashCode();
        }
    }

Deuxièmement, nous appliquons la KeyEqualityComparer à la fonction Intersect:

var list3= list1.Intersect(list2, new KeyEqualityComparer<ClassToCompare>(s => s.Id));
15
Dragos Durlut

Vous pouvez le faire, mais dans le formulaire actuel, vous souhaitez utiliser la méthode d'extension Where.

var results = original.Where(x => yourEnumerable.Contains(x.ID));

Intersect d'autre part trouvera des éléments qui sont dans les deux IEnumerable. Si vous cherchez juste une liste d'ID, vous pouvez faire ce qui suit qui tire parti de Intersect

var ids = original.Select(x => x.ID).Intersect(yourEnumerable);
9
David Pfeffer

Un moyen simple serait:

IEnumerable<ClassA> result = original.Where(a => idsToFind.contains(a.ID));
5
bruno conde

Utilisez la méthode pour filtrer les résultats:

var result = original.Where(o => idsToFind.Contains(o.ID));
1
Ahmad Mageed