I understand how to do a Distinct() on a IEnumerable and that I have to create an IEqualityComparer for more advanced stuff however is there a way in which you can tell which duplicated item to return?
For example say you have a List<T>
List<MyClass> test = new List<MyClass>();
test.Add(new MyClass {ID = 1, InnerID = 4});
test.Add(new MyClass {ID = 2, InnerID = 4});
test.Add(new MyClass {ID = 3, InnerID = 14});
test.Add(new MyClass {ID = 4, InnerID = 14});
You then do:
var distinctItems = test.Distinct(new DistinctItemComparer());
class DistinctItemComparer : IEqualityComparer<MyClass> {
public bool Equals(MyClass x, MyClass y) {
return x.InnerID == y.InnerID;;
}
public int GetHashCode(MyClassobj) {
return obj.InnerID.GetHasCode();
}
}
This code will return the classes with ID 1 and 3. Is there a way to return the ID matches 2 & 4.
I don't believe it's actually guaranteed, but I'd be very surprised to see the behaviour of Distinct change from returning items in the order they occur in the source sequence.
So, if you want particular items, you should order your source sequence that way. For example:
items.OrderByDescending(x => x.Id)
.Distinct(new DistinctItemComparer());
Note that one alternative to using Distinct with a custom comparer is to use DistinctBy from MoreLINQ:
items.OrderByDescending(x => x.Id)
.DistinctBy(x => x.InnerId);
Although you can't guarantee that the normal LINQ to Objects ordering from Distinct won't change, I'd be happy to add a guarantee to MoreLINQ :) (It's the only ordering that is sensible anyway, to be honest.)
Yet another alternative would be to use GroupBy instead - then for each inner ID you can get all the matching items, and go from there.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With