2010-03-04 14 views
40

Jeśli mam IEnumerable, gdzie ClassA udostępnia właściwość ID typu long. Czy można użyć kwerendy Linq do pobrania wszystkich wystąpień klasy ClassA o identyfikatorze należącym do drugiej grupy IEnumerable?Intersect LINQ query

Innymi słowy, czy można to zrobić?

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

gdzie pierwotny jest IEnumerable<ClassA> i idsToFind jest IEnumerable<long>.

Odpowiedz

50

Tak.

Tak jak inne osoby odpowiedziały, można użyć Where, ale będzie to bardzo nieefektywne w przypadku dużych zestawów.

Jeśli wydajność jest problemem, można zadzwonić Join:

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

Jeśli idsToFind może zawierać duplikatów, musisz albo zadzwonić Distinct() na identyfikatorach lub na wynikach lub wymienić Join z GroupJoin (The parametry do GroupJoin byłyby takie same).

+0

To właśnie szukałam, dziękuję. W jakiś sposób nie udało mi się tego w moim oryginalnym pytaniu, ale idsToFind = IEnumerable . Jeszcze raz dziękuję. –

+1

Każdy pomysł, w którym rozmiar 'original' lub' idsToFind' 'Join' zaczyna być bardziej wydajny niż rozwiązanie' Where'/'Contains'? Mogę sobie wyobrazić, że na małych listach (może 20-30 pozycji) "Dołącz" ma zbyt wiele kosztów? – Tobias

1

Użyj metody Where filtrować wyniki:

var result = original.Where(o => idsToFind.Contains(o.ID)); 
5

Prostym sposobem byłoby:

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

Można to zrobić, ale w obecnej formie, którą chcesz użyć metoda rozszerzenia Where.

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

Intersect z drugiej strony znajdzie elementy, które są w obu IEnumerable wieku. Jeśli szukasz tylko liście identyfikatorów, można wykonać następujące czynności który wykorzystuje Intersect

var ids = original.Select(x => x.ID).Intersect(yourEnumerable); 
13

Zamieść odpowiedź, używając Intersect.

Jest to przydatne, jeśli chcesz przeciąć 2 IEnumerables tego samego typu.

Najpierw będziemy potrzebować 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(); 
     } 
    } 

drugie stosujemy KeyEqualityComparer do funkcji Intersect:

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