开发者

Linq Distinct based on property of object

Is it possible to get the distinct elements of a List based on a property of the objects in the List?

Someting like: Distinct(x => x.id)

What's not usefull for me is following: .Select(x => x.id).Distinct() because then I would get back a List<int>开发者_JAVA百科; instead of List<MyClass>


That sounds like a grouping construct to me, because you need to decide which of the supposedly identical object you actually want to return

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

Just because Id is identical across multiple items doesn't mean that the items are identical on other properties, so you need to explicitly decide which item is returned.


What you can do is implement your own IEqualityComparer<T> and pass that to 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();
    }
}

Then:

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


You need DistinctBy. It's not part of the standard .NET libraries, but Jon Skeet made an implementation of it for Linq to objects here. It's also included in morelinq.


There is an overload on Enumerable.Distinct() that takes IEqualityComparer.

Here's an example where I used it to filter integers by parity:

    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);
    }

It's clumsy; DistinctBy would be cleaner.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜