Distinct by property of class with LINQ [duplicate

2020-01-22 13:13发布

I have a collection:

List<Car> cars = new List<Car>();

Cars are uniquely identified by their property CarCode.

I have three cars in the collection, and two with identical CarCodes.

How can I use LINQ to convert this collection to Cars with unique CarCodes?

标签: c# linq distinct
9条回答
戒情不戒烟
2楼-- · 2020-01-22 13:34

You can use grouping, and get the first car from each group:

List<Car> distinct =
  cars
  .GroupBy(car => car.CarCode)
  .Select(g => g.First())
  .ToList();
查看更多
▲ chillily
3楼-- · 2020-01-22 13:34

Use MoreLINQ, which has a DistinctBy method :)

IEnumerable<Car> distinctCars = cars.DistinctBy(car => car.CarCode);

(This is only for LINQ to Objects, mind you.)

查看更多
甜甜的少女心
4楼-- · 2020-01-22 13:34

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);
查看更多
兄弟一词,经得起流年.
5楼-- · 2020-01-22 13:35

Same approach as Guffa but as an extension method:

public static IEnumerable<T> DistinctBy<T, TKey>(this IEnumerable<T> items, Func<T, TKey> property)
{
    return items.GroupBy(property).Select(x => x.First());
}

Used as:

var uniqueCars = cars.DistinctBy(x => x.CarCode);
查看更多
beautiful°
6楼-- · 2020-01-22 13:48

Another way to accomplish the same thing...

List<Car> distinticBy = cars
    .Select(car => car.CarCode)
    .Distinct()
    .Select(code => cars.First(car => car.CarCode == code))
    .ToList();

It's possible to create an extension method to do this in a more generic way. It would be interesting if someone could evalute performance of this 'DistinctBy' against the GroupBy approach.

查看更多
戒情不戒烟
7楼-- · 2020-01-22 13:49

You can't effectively use Distinct on a collection of objects (without additional work). I will explain why.

The documentation says:

It uses the default equality comparer, Default, to compare values.

For objects that means it uses the default equation method to compare objects (source). That is on their hash code. And since your objects don't implement the GetHashCode() and Equals methods, it will check on the reference of the object, which are not distinct.

查看更多
登录 后发表回答