Использование LINQ для поиска дубликатов в нескольких свойствах - PullRequest
20 голосов
/ 08 апреля 2011

Дан класс со следующим определением:

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 оба = 1

Ответы [ 3 ]

42 голосов
/ 08 апреля 2011

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

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

var duplicates = items.GroupBy(i => new {i.ValueA, i.ValueB})
  .Where(g => g.Count() > 1)
  .Select(g => g.Key);
4 голосов
/ 07 сентября 2013

Вы можете просто использовать 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();

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

1 голос
/ 08 апреля 2011

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».

...