2011-02-07 99 views
4

我有List<Location> locations重复列表中的重复项

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

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

回答

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); 
} 
+1

.ToList()枚举集合。不要这样做,如果你不需要它...... :-) – 2011-02-07 12:56:18

4

创建的IEqualityComparer <位置>将是你的首要任务之一(它允许您比较基于属性,你所选择的对象)。

如果你想使用Linq获得独特的项目,那么你可以使用Distinct()方法。

然后,您可以从原始列表中删除这些项目,这些项目将为您提供一组重复项。

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

您将需要使用自定义相等比较的独特,但除外。