Подтвердить что ты не робот

Использование LINQ для поиска дубликатов по нескольким свойствам

Учитывая класс со следующим определением:

public class MyTestClass
{
    public int ValueA { get; set; }
    public int ValueB { get; set; }
}

Как можно дублировать значения в массиве MyTestClass []?

Например,

MyTestClass[] items = new MyTestClass[3];
items[0] = new MyTestClass { ValueA = 1, ValueB = 1 };
items[1] = new MyTestClass { ValueA = 0, ValueB = 1 };
items[2] = new MyTestClass { ValueA = 1, ValueB = 1 };

Содержит дубликат, поскольку есть два объекта MyTestClass, где ValueA и ValueB both = 1

4b9b3361

Ответ 1

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

Вот как вы изолировали бы обманы:

var duplicates = items.GroupBy(i => new {i.ValueA, i.ValueB})
  .Where(g => g.Count() > 1)
  .Select(g => g.Key);

Ответ 2

Вы можете просто использовать Jon Skeet DistinctBy и Except вместе, чтобы найти дубликаты. См. этот ответ для объяснения DistinctBy.

MyTestClass[] items = new MyTestClass[3];
items[0] = new MyTestClass { ValueA = 1, ValueB = 1 };
items[1] = new MyTestClass { ValueA = 0, ValueB = 1 };
items[2] = new MyTestClass { ValueA = 1, ValueB = 1 };

MyTestClass [] distinctItems = items.DistinctBy(p => new {p.ValueA, p.ValueB}).ToArray();
MyTestClass [] duplicates = items.Except(distinctItems).ToArray();

Он возвращает только один элемент, а не оба дубликата.

Ответ 3

MyTestClass должен реализовать метод Equals.

public bool Equals(MyTestClass x, MyTestClass y)
{
    if (Object.ReferenceEquals(x, y)) return true;

    if (Object.ReferenceEquals(x, null) ||
        Object.ReferenceEquals(y, null))
            return false;

        return x.ValueA == y.ValueA && y.ValueB == y.ValueB;
}

Здесь у вас есть хорошая статья об этом.

После этого вы можете получить "чистый" список MyTestClass с помощью метода "Distinct".