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 to do, this is not the question). What I if want to use Distinct on a list of an Object on one or more properties of the object?
Example: If an object is Person
, with Property Id
. How can I get all Person and use Distinct
on them with the property Id
of the object?
Person1: Id=1, Name="Test1"
Person2: Id=1, Name="Test1"
Person3: Id=2, Name="Test2"
How can I get just Person1 and Person3? Is that possible?
If it's not possible with LINQ, what would be the best way to have a list of Person
depending on some of its properties in .NET 3.5?
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:
So to find the distinct values using just the
Id
property, you could use:And to use multiple properties, you can use anonymous types, which implement equality appropriately:
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.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.
You can do this with the standard
Linq.ToLookup()
. This will create a collection of values for each unique key. Just select the first item in the collectionSolution first group by your fields then select firstordefault item.
I think it is enough:
The following code is functionally equivalent to Jon Skeet's answer.
Tested on .NET 4.5, should work on any earlier version of LINQ.
Incidentially, check out Jon Skeet's latest version of DistinctBy.cs on Google Code.