2010-03-04 15 views
40

Eğer ClassA'nın uzunluğundaki bir ID özelliğini gösterdiği bir IEnumerable'ım varsa. İkinci bir IEnumerable'a ait olan kimliği olan ClassA'nın tüm örneklerini almak için bir Linq sorgusu kullanmak mümkün mü? Başka bir deyişle, bu yapılabilir mi? Orijinal bir IEnumerable<ClassA> ve idsToFindIntersect LINQ sorgusu

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

IEnumerable<long> olup.

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

cevap

50

Evet yararlanır aşağıdakileri yapabilirsiniz.

Diğer kişilerin yanıt verdiği gibi, Where'u kullanabilirsiniz, ancak büyük kümeler için son derece verimsiz olacaktır. Performans bir sorun olacaksa

, sen Join arayabilirsiniz: çiftleri içerebilir

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

idsToFind varsa, (kimliklere veya sonuçlarına Distinct() arayın veya GroupJoin ile Join değiştirmek ya gerekecektir GroupJoin için parametreler aynı olurdu).

+0

Bu aradığım buydu, teşekkürler. Her nasılsa, bu benim özgün sorgulamada yapmadım ama idsToFind = IEnumerable . Tekrar teşekkürler. –

+1

'Join'' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ''' çözümden daha verimli olmaya başlar? Küçük listeler için (belki 20-30 madde) 'Katıl' ın fazla yükü olduğunu hayal edebiliyorum. – Tobias

1

sonuçları filtrelemek için Where yöntemi kullanın Where uzantı yöntemi. Öte yandan

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

Intersect

hem IEnumerable 's olan unsurları bulacaksınız. Eğer kimlikleri sadece bir liste arıyorsanız, sen Intersect

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

basit bir yolu olurdu:

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

Bunu yapabilirsin, ama mevcut haliyle, kullanmak isterdim

13

Intersect kullanarak bir yanıt göndereceğim.

Aynı türde 2 IEnumerables kesiştirmek istiyorsanız bu özellik yararlıdır.

Önce bir EqualityComparer gerekir:

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(); 
     } 
    } 

İkincisi biz Intersect işlevine KeyEqualityComparer geçerlidir:

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