LINQ's Distinct() on a particular property

后端 未结 20 2077
一向
一向 2020-11-21 05:05

I am playing with LINQ to learn about it, but I can\'t figure out how to use Distinct when I do not have a simple list (a simple list of integers is pretty easy

相关标签:
20条回答
  • 2020-11-21 05:34

    EDIT: This is now part of MoreLINQ.

    What you need is a "distinct-by" effectively. I don't believe it's part of LINQ as it stands, although it's fairly easy to write:

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

    So to find the distinct values using just the Id property, you could use:

    var query = people.DistinctBy(p => p.Id);
    

    And to use multiple properties, you can use anonymous types, which implement equality appropriately:

    var query = people.DistinctBy(p => new { p.Id, p.Name });
    

    Untested, but it should work (and it now at least compiles).

    It assumes the default comparer for the keys though - if you want to pass in an equality comparer, just pass it on to the HashSet constructor.

    0 讨论(0)
  • 2020-11-21 05:35

    Solution first group by your fields then select firstordefault item.

        List<Person> distinctPeople = allPeople
       .GroupBy(p => p.PersonId)
       .Select(g => g.FirstOrDefault())
       .ToList();
    
    0 讨论(0)
  • 2020-11-21 05:40

    I've written an article that explains how to extend the Distinct function so that you can do as follows:

    var people = new List<Person>();
    
    people.Add(new Person(1, "a", "b"));
    people.Add(new Person(2, "c", "d"));
    people.Add(new Person(1, "a", "b"));
    
    foreach (var person in people.Distinct(p => p.ID))
        // Do stuff with unique list here.
    

    Here's the article (now in the Web Archive): Extending LINQ - Specifying a Property in the Distinct Function

    0 讨论(0)
  • 2020-11-21 05:40

    You can use DistinctBy() for getting Distinct records by an object property. Just add the following statement before using it:

    using Microsoft.Ajax.Utilities;

    and then use it like following:

    var listToReturn = responseList.DistinctBy(x => x.Index).ToList();
    

    where 'Index' is the property on which i want the data to be distinct.

    0 讨论(0)
  • 2020-11-21 05:41

    You should be able to override Equals on person to actually do Equals on Person.id. This ought to result in the behavior you're after.

    0 讨论(0)
  • 2020-11-21 05:43

    You could also use query syntax if you want it to look all LINQ-like:

    var uniquePeople = from p in people
                       group p by new {p.ID} //or group by new {p.ID, p.Name, p.Whatever}
                       into mygroup
                       select mygroup.FirstOrDefault();
    
    0 讨论(0)
提交回复
热议问题