从列表中筛选重复项

时间:2011-02-07 12:28:08

标签: c# .net linq list duplicates

我有List<Location> locations

Location类有一个属性Coordinates - 假设一个字符串。

如何删除具有重复坐标的位置并将它们放入单独的列表中?有两个列表 - 一个用于重复,一个没有。

2 个答案:

答案 0 :(得分:4)

创建IEqualityComparer&lt;地点&gt;将是您的第一个任务之一(允许您根据您选择的属性比较对象)。

如果您想使用Linq获取唯一项目,则可以使用Distinct()方法。

然后,您可以从原始列表中删除这些项目,这将为您留下重复的集合。

var distinctObjects = originalList.Distinct();
var duplicateList = originalList.Except(distinctObjects);

您需要为distinct使用自定义相等比较器,但 not 除外。

答案 1 :(得分:3)

这取决于你的意思,真的。如果您想要一个代表列表,另一个列出剩余的重复项,您可以这样做:

var locationsByCoordinates = locations.ToLookup(location => location.Coordinates);

var distinct = locationsByCoordinates.Select(group => group.First())
                                     .ToList();

var duplicates = locationsByCoordinates.SelectMany(group => group.Skip(1))
                                       .ToList(); 

另一方面,如果您想要一个列表用于那些唯一的项目,而另一个列表用于那些不是唯一的项目:

var distinct = locationsByCoordinates.Where(group => group.Count() == 1)
                                     .Select(group => group.Single())
                                     .ToList();

var duplicates = locationsByCoordinates.Where(group => group.Count() != 1)
                                       .SelectMany(group => group)
                                       .ToList();

虽然它枚举了两次查找,但效率稍低。稍微好一点就是:

var distinct = new List<Location>();
var duplicates = new List<Location>();

foreach(var group in locationsByCoordinates)
{
    var target = group.Count() == 1 ? distinct : duplicates;
    target.AddRange(group);
}