LINQ: Distinct values

balint picture balint · Jun 15, 2009 · Viewed 192.1k times · Source

I have the following item set from an XML:

id           category

5            1
5            3
5            4
5            3
5            3

I need a distinct list of these items:

5            1
5            3
5            4

How can I distinct for Category AND Id too in LINQ?

Answer

Jon Skeet picture Jon Skeet · Jun 15, 2009

Are you trying to be distinct by more than one field? If so, just use an anonymous type and the Distinct operator and it should be okay:

var query = doc.Elements("whatever")
               .Select(element => new {
                             id = (int) element.Attribute("id"),
                             category = (int) element.Attribute("cat") })
               .Distinct();

If you're trying to get a distinct set of values of a "larger" type, but only looking at some subset of properties for the distinctness aspect, you probably want DistinctBy as implemented in MoreLINQ in DistinctBy.cs:

 public static IEnumerable<TSource> DistinctBy<TSource, TKey>(
     this IEnumerable<TSource> source,
     Func<TSource, TKey> keySelector,
     IEqualityComparer<TKey> comparer)
 {
     HashSet<TKey> knownKeys = new HashSet<TKey>(comparer);
     foreach (TSource element in source)
     {
         if (knownKeys.Add(keySelector(element)))
         {
             yield return element;
         }
     }
 }

(If you pass in null as the comparer, it will use the default comparer for the key type.)