2011-07-25 162 views
3

我有兩個不同的自定義類型的兩個列表。這兩種類型共享2個共同屬性。C#LINQ比較列表值

例如:

List<foo>; 
List<bar>; 

他們都有屬性,例如,一個名爲名字和年齡。

我想返回一個包含所有條形對象的新列表,其中條形的名稱和年齡屬性存在於任何foo對象中。 什麼是最好的方法來做到這一點?

感謝

回答

11

假設共享屬性實現平等等正常,你可能想要做這樣的事情:

// In an extensions class somewhere. This should really be in the standard lib. 
// We need it for the sake of type inference. 
public static HashSet<T> ToHashSet<T>(this IEnumerable<T> items) 
{ 
    return new HashSet<T>(items); 
} 

var shared = foos.Select(foo => new { foo.SharedProperty1, foo.SharedProperty2 }) 
       .ToHashSet(); 

var query = bars.Where(bar => shared.Contains(new { bar.SharedProperty1, 
                bar.SharedProperty2 })); 

其他選項使用連接肯定會起作用 - 但我發現這更清楚地表達這樣的想法,即您只想查看每個bar條目,即使有幾個foo項目與該屬性。

+1

如果有很多foos並且希望它運行得很快,'HashSet'就是正確的工具。 – Zebi

+0

謝謝喬恩。他們目前不實行平等。這是否意味着覆蓋Equals和GetHashCode? –

+0

@達倫:是的。當然,默認的實現可能已經足夠好了 - 這取決於你是否想要任何自定義的平等。 –

3

聽起來像是你需要一個連接:

var fooList = new List<foo>(); 
var barList = new List<bar>(); 

// fill the lists 

var results = from f in fooList 
       join b in barList on 
        new { f.commonPropery1, f.commonProperty2 } 
        equals 
        new { b.commonProperty1, commonProperty2 = b.someOtherProp } 
       select new { f, b }; 
1

Any應該工作,如果是無關緊要多少Foo的比賽:

var selectedBars = bars.Where(bar => 
           foos.Any(foo => foo.Property1 == bar.Property1 
              && foo.Property2 == bar.Property2)); 

如果所有的Foo應該匹配使用All

var selectedBars = bars.Where(bar => 
           foos.All(foo => foo.Property1 == bar.Property1 
              && foo.Property2 == bar.Property2)); 

如果FOOS名單是大量使用的一個HashSet中指出, John Skeets回答。