Как найти и удалить дублирующиеся объекты в наборе с помощью LINQ?

У меня есть простой класс, представляющий объект. Это имеет 5 свойств (дата, 2 десятичных числа, целое число и строка). У меня есть класс набора, полученный из CollectionBase, который является контейнерным классом для содержания нескольких объектов от моего первого класса.

Мой вопрос, я хочу удалить дублирующиеся объекты (например, объекты, которые имеют ту же дату, те же десятичные числа, те же целые числа и ту же строку). Существует ли запрос LINQ, который я могу записать, чтобы найти и удалить дубликаты? Или найдите их по крайней мере?

7
задан nawfal 23 September 2013 в 19:18
поделиться

2 ответа

Вы можете удалить дубликаты с помощью оператора Distinct .

Есть две перегрузки: одна использует компаратор проверки на равенство по умолчанию для вашего типа (который для настраиваемого типа вызывает метод Equals () для этого типа). Второй позволяет вам предоставить свой собственный компаратор проверки на равенство. Оба они возвращают новую последовательность , представляющую ваш исходный набор без дубликатов. Ни одна из перегрузок на самом деле не изменяет вашу первоначальную коллекцию - они обе возвращают новую последовательность, исключающую дубликаты. .

Если вы хотите просто найти дубликаты, вы можете использовать GroupBy для этого:

var groupsWithDups = list.GroupBy( x => new { A = x.A, B = x.B, ... }, x => x ) 
                         .Where( g => g.Count() > 1 );

Чтобы удалить дубликаты из чего-то вроде IList <> , вы можете сделать:

yourList.RemoveAll( yourList.Except( yourList.Distinct() ) );
11
ответ дан 6 December 2019 в 14:00
поделиться

Если ваш простой класс использует Equals способом, который удовлетворяет вашим требованиям, тогда вы можете использовать метод Distinct

var col = ...;
var noDupes = col.Distinct();

. Если нет, вам нужно будет предоставить экземпляр IEqualityComparer , который сравнивает значения так, как вы хотите. Например (пустые проблемы для краткости игнорируются)

public class MyTypeComparer : IEqualityComparer<MyType> {
  public bool Equals(MyType left, MyType right) {
    return left.Name == right.Name;
  }
  public int GetHashCode(MyType type) {
    return 42;
  }
}

var noDupes = col.Distinct(new MyTypeComparer());

Обратите внимание, что использование константы для GetHashCode является преднамеренным. Без подробных сведений о семантике MyType невозможно написать эффективную и правильную функцию хеширования. Вместо эффективной функции хеширования я использовал константу, которая верна независимо от семантики типа.

4
ответ дан 6 December 2019 в 14:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: