Feedback

C# - linq DistinctBy for IEnumerable

Veröffentlicht von am 11/3/2015
(2 Bewertungen)
Das snippet erlaubt ein DistinctBy mit propertySelector um die gewünschte property die eindeutig sein muss auszuwählen.

Die implementierung benötigt c# 6!

Durch das nutzen des selben namespaces wie die .NET Linq methoden ist diese Methode immer verfügbar wenn System.Linq eingebunden ist.

Usage:
var distinctByNames = items.Distinct(x => x.Name);



namespace System.Linq;
{
    using System;
    using System.Collections.Generic;

    public static class EnumerableExtensions
    {
        public static IEnumerable<TSource> Distinct<TSource, TProperty>(this IEnumerable<TSource> target, Func<TSource, TProperty> propertySelector)
        {
            return target.Distinct(propertySelector, EqualityComparer<TProperty>.Default);
        }

        public static IEnumerable<TSource> Distinct<TSource, TProperty>(this IEnumerable<TSource> target, Func<TSource, TProperty> propertySelector,
            IEqualityComparer<TProperty> propertyEqualityComparer)
        {
            return target.Distinct(new PropertyComparer<TSource, TProperty>(propertySelector, propertyEqualityComparer));
        }

        private class PropertyComparer<TElement, TProperty> : IEqualityComparer<TElement>
        {
            private readonly Func<TElement, TProperty> propertySelector;
            private readonly IEqualityComparer<TProperty> propertyComparer;

            public PropertyComparer(Func<TElement, TProperty> propertySelector)
            {
                this.propertySelector = propertySelector;
            }

            public PropertyComparer(Func<TElement, TProperty> propertySelector, IEqualityComparer<TProperty> propertyComparer)
            {
                this.propertySelector = propertySelector;
                this.propertyComparer = propertyComparer;
            }

            public bool Equals(TElement x, TElement y)
            {
                return this.propertyComparer?.Equals(this.propertySelector(x), this.propertySelector(y)) ?? this.propertySelector(x).Equals(this.propertySelector(y));
            }

            public int GetHashCode(TElement obj)
            {
                return this.propertyComparer?.GetHashCode(this.propertySelector(obj)) ?? this.propertySelector(obj).GetHashCode();
            }
        }
    }
}
Abgelegt unter Linq, Distinct.

3 Kommentare zum Snippet

Koopakiller schrieb am 11/3/2015:
Warum DistinctBy und nicht Distinct? Letzteres würde einen direkten Bezug zu den bereits existierenden Methoden darstellen, nur dass du eben einen Delegaten statt einem IEqualityComparer entgegen nimmst.
Console schrieb am 11/3/2015:
@Koopakiller Stimmt könnte man noch anpassen, die Unterscheidung sollte eigentlich nicht nötig sein.
Koopakiller schrieb am 11/4/2015:
Dann passe es an ;)
Über dem Snippet ist ein Link zum bearbeiten des Snippets (nur für dich sichtbar)
 

Logge dich ein, um hier zu kommentieren!