2010-04-28 14 views
5

Her birinde çeşitli özelliklere sahip nesneler koleksiyonum var. Bu koleksiyondaki çoğu mülk için genellikle farklı değerlerin bir listesini almam gerekir. IEqualityComparer'ı bu türde uygularsam, koleksiyondaki ayrı nesneleri elde etmek için bana tek bir kriter verir. Bu koleksiyon için birden fazla ölçütte Distinct'ı nasıl arayabilirim? ÖrneğinListe <T> .Distinct() in C# - EqualityComparer için çoklu ölçütler?

,

class Product { 
    string name ; 
    string code ; 
    string supplier ; 
//etc 
} 

, ürün nesnelerin bir listesi düşünün. Bazen, listedeki farklı isimlerin listesini almak istiyorum ve bir süre sonra, ayrı bir tedarikçinin listesi. IEqualityComparer'ın uygulanmasına dayalı olarak, bu ürünlerin bir listesinde Distinct adını verirsem, her zaman amacımı yerine getirmeyecek olan aynı kriterleri kullanır.

cevap

6

Bir IEqualityComparer bağımsız değişkenini kabul eden Distinct() overload'u kullanabilirsiniz.

13

Distinct numaralı telefon numaraları için farklı aramalar için farklı IEqualityComparer uygulamaları sunmanız yeterlidir. IEquatable ve IEqualityComparer arasındaki farka dikkat edin; genellikle bir tür, IEqualityComparer'u kendi başına uygulamamalıdır (bu nedenle Product, IEqualityComparer<Product>'u uygulayamaz). Böyle vb ProductNameComparer, ProductCodeComparer olarak farklı uygulamaları, olurdu

Ancak, başka bir alternatif de Eşittir ve GetHashCode için fonksiyon argümanları kabul eden bir karşılaştırıcısı yaratabilecek MoreLINQ

var distinctProducts = products.DistinctBy(p => p.name); 
+0

cevap olarak ama Hans 2 dakika erken cevap için seçilen olurdu. – Bhaskar

3

yılında DistinctBy kullanmaktır yöntemleri.

class Foo 
{ 
    public string Name { get; set; } 
    public int Id { get; set; } 
}  

class FooComparer : IEqualityComparer<Foo> 
{ 
    public FooComparer(Func<Foo, Foo, bool> equalityComparer, Func<Foo, int> getHashCode) 
    { 
     EqualityComparer = equalityComparer; 
     HashCodeGenerator = getHashCode; 
    } 

    Func<Foo, Foo, bool> EqualityComparer; 
    Func<Foo, int> HashCodeGenerator; 

    public bool Equals(Foo x, Foo y) 
    { 
     return EqualityComparer(x, y); 
    } 

    public int GetHashCode(Foo obj) 
    { 
     return HashCodeGenerator(obj); 
    } 
} 

gibi bir şey ...

List<Foo> foos = new List<Foo>() { new Foo() { Name = "A", Id = 4 }, new Foo() { Name = "B", Id = 4 } }; 
var list1 = foos.Distinct(new FooComparer((x, y) => x.Id == y.Id, f => f.Id.GetHashCode()));