NET[C#]LINQ中如何按实体的某个属性去重后返回不重复的集合?
问题描述
比如有如下实体集合:
Person1: Id=1, Name="Test1" Person2: Id=1, Name="Test1" Person3: Id=2, Name="Test2"
如何使用LINQ按 Person.Id 去重,返回的集合只包含 Person1 和 Person3 ?
方案一
创建一个静态扩展类:
public static IEnumerable<TSource> DistinctBy<TSource, TKey> (this IEnumerable<TSource> source, Func<TSource, TKey> keySelector) { HashSet<TKey> seenKeys = new HashSet<TKey>(); foreach (TSource element in source) { if (seenKeys.Add(keySelector(element))) { yield return element; } } }
调用方法:
var query = people.DistinctBy(p => p.Id);
如果需要按多个属性去重,则可以使用匿名对象,如:
var query = people.DistinctBy(p => new { p.Id, p.Name });
方案二
List<Person> distinctPeople = allPeople .GroupBy(p => p.PersonId) .Select(g => g.First()) .ToList();
多属性去重:
List<Person> distinctPeople = allPeople .GroupBy(p => new {p.PersonId, p.FavoriteColor} ) .Select(g => g.First()) .ToList();
方案三
var uniquePeople = from p in people group p by new {p.ID} //or group by new {p.ID, p.Name, p.Whatever} into mygroup select mygroup.FirstOrDefault();
方案四
Persons.ToLookup(p => p.Id).Select(coll => coll.First());
方案五
var result = people.Where(p => !people.Any(q => (p != q && p.Id == q.Id)));