问题描述
在.NET/C#程序开发中,当前有如下的实体对象集合List<Car>
:
List<Car> cars = new List<Car>();
其中,List<Car>
集合中的每个Car
对象都是以CarCode
属性来作为标识的。假设,当前这个List<Car>
集合中有本个元素,其中的两个Car
的CarCode
属性完全相同,如:
List<Car> cars =new List<Car>{
new Car{Id=1,CarCode="CC00001",Name="Car001"},
new Car{Id=2,CarCode="CC00002",Name="Car002"},
new Car{Id=3,CarCode="CC00001",Name="Car003"}
};
现在,在.NET/C#的程序开发中,如何使用LINQ
从集合List<Car>
中查询出惟一属性CarCode
的集合?
方案一
使用linq
lambda
中的’GroupBy(…)’方法,如下:
List<Car> distinct =
cars
.GroupBy(car => car.CarCode)
.Select(g => g.First())
.ToList();
方案二
使用第三方组件:MoreLINQ
的DistinctBy(...)
方法来快速实现,如下:
IEnumerable<Car> distinctCars = cars.DistinctBy(car => car.CarCode);
方案三
实现一个DistinctBy(...)
的静态扩展方法,如下:
public static IEnumerable<T> DistinctBy<T, TKey>(this IEnumerable<T> items, Func<T, TKey> property)
{
return items.GroupBy(property).Select(x => x.First());
}
调用方式:
var uniqueCars = cars.DistinctBy(x => x.CarCode);
方案四
实现一个关于接口IEqualityComparer
的类,然后使用Distinct()
扩展方法,如下:
class CarEqualityComparer : IEqualityComparer<Car>
{
#region IEqualityComparer<Car> Members
public bool Equals(Car x, Car y)
{
return x.CarCode.Equals(y.CarCode);
}
public int GetHashCode(Car obj)
{
return obj.CarCode.GetHashCode();
}
#endregion
}
调用方式:
var uniqueCars = cars.Distinct(new CarEqualityComparer());
方案五
使用Func<TSource,TResult>
表达式实现的另外一个静态扩展方法,可以自定义实现对象的表达式,如下:
public static IEnumerable<TSource> Distinct<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector)
{
HashSet<TResult> set = new HashSet<TResult>();
foreach(var item in source)
{
var selectedValue = selector(item);
if (set.Add(selectedValue))
yield return item;
}
}
版权声明:本作品系原创,版权归码友网所有,如未经许可,禁止任何形式转载,违者必究。
发表评论
登录用户才能发表评论, 请 登 录 或者 注册