LINQ's Distinct() on a particular property

后端 未结 20 2021
一向
一向 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 06:01

    Personally I use the following class:

    public class LambdaEqualityComparer<TSource, TDest> : 
        IEqualityComparer<TSource>
    {
        private Func<TSource, TDest> _selector;
    
        public LambdaEqualityComparer(Func<TSource, TDest> selector)
        {
            _selector = selector;
        }
    
        public bool Equals(TSource obj, TSource other)
        {
            return _selector(obj).Equals(_selector(other));
        }
    
        public int GetHashCode(TSource obj)
        {
            return _selector(obj).GetHashCode();
        }
    }
    

    Then, an extension method:

    public static IEnumerable<TSource> Distinct<TSource, TCompare>(
        this IEnumerable<TSource> source, Func<TSource, TCompare> selector)
    {
        return source.Distinct(new LambdaEqualityComparer<TSource, TCompare>(selector));
    }
    

    Finally, the intended usage:

    var dates = new List<DateTime>() { /* ... */ }
    var distinctYears = dates.Distinct(date => date.Year);
    

    The advantage I found using this approach is the re-usage of LambdaEqualityComparer class for other methods that accept an IEqualityComparer. (Oh, and I leave the yield stuff to the original LINQ implementation...)

    0 讨论(0)
  • 2020-11-21 06:01

    In case you need a Distinct method on multiple properties, you can check out my PowerfulExtensions library. Currently it's in a very young stage, but already you can use methods like Distinct, Union, Intersect, Except on any number of properties;

    This is how you use it:

    using PowerfulExtensions.Linq;
    ...
    var distinct = myArray.Distinct(x => x.A, x => x.B);
    
    0 讨论(0)
提交回复
热议问题