Saa*_*per 19 c# linq lambda iequalitycomparer
我在C#中有一个List <>对象,我需要一种方法来返回列表中被认为是重复的对象.我不需要Distinct结果集,我需要一个我将从我的存储库中删除的项目列表.
为了这个例子,让我说我有一个"汽车"类型的列表,我需要知道这些汽车中哪一个与列表中的另一个颜色相同.以下是列表中的汽车及其颜色属性:
Car1.Color = Red;
Car2.Color = Blue;
Car3.Color = Green;
Car4.Color = Red;
Car5.Color = Red;
Run Code Online (Sandbox Code Playgroud)
对于这个例子,我需要结果(IEnumerable <>,List <>或其他)来包含Car4和Car5,因为我想从我的存储库或数据库中删除这些,这样我的存储库中每种颜色只有一辆汽车.任何帮助,将不胜感激.
Jon*_*eet 29
昨天,当我试图写一个"与投影截然不同"时,我无意中编码了这个.我加了一个!当我不应该,但这次是正确的:
public static IEnumerable<TSource> DuplicatesBy<TSource, TKey>
(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
{
HashSet<TKey> seenKeys = new HashSet<TKey>();
foreach (TSource element in source)
{
// Yield it if the key hasn't actually been added - i.e. it
// was already in the set
if (!seenKeys.Add(keySelector(element)))
{
yield return element;
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后你用它来调用它:
var duplicates = cars.DuplicatesBy(car => car.Color);
Run Code Online (Sandbox Code Playgroud)
Gre*_*ech 17
var duplicates = from car in cars
group car by car.Color into grouped
from car in grouped.Skip(1)
select car;
Run Code Online (Sandbox Code Playgroud)
这会按颜色对汽车进行分组,然后跳过每组的第一个结果,将每组中的剩余部分归为单个序列.
如果您对要保留哪一个有特殊要求,例如,如果汽车有一个Id属性并且您想要保持最低的汽车Id,那么您可以在那里添加一些订购,例如
var duplicates = from car in cars
group car by car.Color into grouped
from car in grouped.OrderBy(c => c.Id).Skip(1)
select car;
Run Code Online (Sandbox Code Playgroud)
这是一个略有不同的Linq解决方案,我认为这使您更明显地尝试做什么:
var s = from car in cars
group car by car.Color into g
where g.Count() == 1
select g.First();
Run Code Online (Sandbox Code Playgroud)
它只是按颜色对汽车进行分组,抛弃所有具有多个元素的组,然后将其余组件放入返回的IEnumerable中.