У меня есть простой класс, представляющий объект. Это имеет 5 свойств (дата, 2 десятичных числа, целое число и строка). У меня есть класс набора, полученный из CollectionBase
, который является контейнерным классом для содержания нескольких объектов от моего первого класса.
Мой вопрос, я хочу удалить дублирующиеся объекты (например, объекты, которые имеют ту же дату, те же десятичные числа, те же целые числа и ту же строку). Существует ли запрос LINQ, который я могу записать, чтобы найти и удалить дубликаты? Или найдите их по крайней мере?
Вы можете удалить дубликаты с помощью оператора 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() ) );
Если ваш простой класс использует 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
невозможно написать эффективную и правильную функцию хеширования. Вместо эффективной функции хеширования я использовал константу, которая верна независимо от семантики типа.