Самый быстрый способ найти дополнение двух коллекций в C # - PullRequest
25 голосов
/ 03 февраля 2010

У меня есть две коллекции типа ICollection<MyType>, называемые c1 и c2. Я хотел бы найти набор элементов в c2, которых нет в c1, где эвристика равенства равна свойству Id в MyType.

Какой самый быстрый способ выполнить это в C # (3.0)?

Ответы [ 3 ]

36 голосов
/ 03 февраля 2010

Использование Enumerable.Except и, в частности, перегрузка , которая принимает IEqualityComparer<MyType>:

var complement = c2.Except(c1, new MyTypeEqualityComparer());

Обратите внимание, что это приводит к разнице в наборах и, следовательно, дубликаты в c2 будут появляться в результирующем IEnumerable<MyType> только один раз. Здесь нужно реализовать IEqualityComparer<MyType> как что-то вроде

class MyTypeEqualityComparer : IEqualityComparer<MyType> {
    public bool Equals(MyType x, MyType y) {
        return x.Id.Equals(y.Id);
    }

    public int GetHashCode(MyType obj) {
        return obj.Id.GetHashCode();
    }
}
3 голосов
/ 03 февраля 2010

При использовании C # 3.0 + Linq:

var complement = from i2 in c2
                 where c1.FirstOrDefault(i1 => i2.Id == i1.Id) == null
                 select i2;

Пройдите через комплект, чтобы получить предметы.

0 голосов
/ 03 февраля 2010
public class MyTypeComparer : IEqualityComparer<MyType>
{
    public MyTypeComparer()
    {    
    }

    #region IComparer<MyType> Members

    public bool Equals(MyType x, MyType y)
    {
        return string.Equals(x.Id, y.Id);
    }

    public int GetHashCode(MyType obj)
    {
        return base.GetHashCode();
    }

    #endregion     
}

Затем, используя Linq:

c3 collection = new collection().add(c1);
c3.add(c2);
var items = c3.Distinct(new MyTypeComparer());

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

...