2011-02-07 133 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); 

您將需要使用自定義相等比較的獨特,但除外。