2010-01-17 6 views
8

Est-il possible d'obtenir les éléments distincts d'un List basé sur une propriété des objets dans le List?Linq Distinct basé sur la propriété de l'objet

someting comme: Distinct(x => x.id)

Qu'est-ce pas pour moi UTILE est le suivant: .Select(x => x.id).Distinct() parce que je retrouverais un List<int> au lieu de List<MyClass>

+0

Presque même que: http://stackoverflow.com/questions/520030/why-is-there-no-linq-method-to-return-distinct-values-by-a-predicate –

Répondre

2

Vous avez besoin DistinctBy. Il ne fait pas partie des bibliothèques .NET standard, mais Jon Skeet en a fait une implémentation pour Linq aux objets here. Il est également inclus dans morelinq.

6

qui sonne comme un groupe de construire pour moi, parce que vous devez décider de l'objet prétendument identique que vous voulez vraiment revenir

var q = from x in foo 
     group x by x.Id into g 
     select g.First(); // or some other selection from g 

Tout simplement parce que Id est identique sur plusieurs éléments ne signifie pas que la les éléments sont identiques sur d'autres propriétés, vous devez donc décider explicitement quel élément est renvoyé.

5

Ce que vous pouvez faire est de mettre en œuvre votre propre IEqualityComparer<T> et passer que pour Distinct:

class SomeType { 
    public int id { get; set; } 
    // other properties 
} 
class EqualityComparer : IEqualityComparer<SomeType> { 
    public bool Equals(SomeType x, SomeType y) { 
     return x.id == y.id; 
    } 

    public int GetHashCode(SomeType obj) { 
     return obj.id.GetHashCode(); 
    } 
} 

Puis:

// elements is IEnumerable<SomeType> 
var distinct = elements.Distinct(new EqualityComparer()); 
// distinct is IEnumerable<SomeType> and contains distinct items from elements 
// as per EqualityComparer 
2

Il y a une surcharge sur Enumerable.Distinct() qui prend IEqualityComparer.

Voici un exemple où je l'ai utilisé pour filtrer les entiers par la parité:

class IntParitiyComparer : IEqualityComparer<int> 
    { 
     public bool Equals(int x, int y) 
     { 
      return x % 2 == y % 2; 
     } 

     public int GetHashCode(int obj) 
     { 
      return obj % 2; 
     } 
    } 

    static void Main(string[] args) 
    { 
     var x = new int[] { 1, 2, 3, 4 }.Distinct(new IntParitiyComparer()); 

     foreach (var y in x) Console.WriteLine(y); 
    } 

Il est maladroit; DistinctBy serait plus propre.

Questions connexes