C#3.0:需要从List <>返回重复项

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)

  • 另一件事:返回所有具有相同键但第一个(以循环顺序)的元素(因此如果你有3个重复,返回2个元素),对我来说可能看起来很奇怪.要么返回所有重复项,要么只返回一次键... (2认同)

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)


Awe*_*own 5

这是一个略有不同的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中.