2011-02-07 2 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() перечисляет коллекцию. Не делайте этого, если вам это не нужно ... :-) –

+1

@Tuomas Hietanen: Хотя верно, OP запрашивает * list * -output. – Ani

4

Создание IEqualityComparer < Locations> будет одним из ваших первых задач (что позволяет сравнивать объекты, основанные на свойствах Вы выбрали).

Если вы хотите получить уникальные предметы с помощью Linq, вы можете использовать метод Distinct().

Затем вы можете удалить предметы из своего первоначального списка, которые оставят вас с коллекцией дубликатов.

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

Вам нужно будет использовать собственный компаратор равенство для различных, но не за исключением.

Смежные вопросы