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

Linq обнаруживает различия в двух списках

У меня есть два списка таких элементов:

До: Питер, Кен, Джулия, Том

После: Питер, Роберт, Джулия, Том

Как вы можете видеть, Кен не работает, и Роберт находится.

Я хочу обнаружить изменения. Мне нужен список изменений в обоих списках. Как мне помочь linq?

4b9b3361

Ответ 1

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

before.Except(after).Union(after.Except(before));

Ответ 2

В качестве альтернативы ответам linq, которые должны пройти оба списка дважды, используйте HashSet.SymmetricExceptWith():

var difference = new HashSet(before);
difference.SymmetricExceptWith(after);

Может быть значительно более эффективным.

Ответ 3

Другой способ:

before.Union(after).Except(before.Intersect(after))

Ответ 4

Вот версия, имеющая сложность O (n), если ваши последовательности упорядочены:

    public static IEnumerable<T> SymmetricDifference<T>(IEnumerable<T> coll1, IEnumerable<T> coll2, IComparer<T> cmp)
    {
        using (IEnumerator<T> enum1 = coll1.GetEnumerator())
        using (IEnumerator<T> enum2 = coll2.GetEnumerator())
        {
            bool enum1valid = enum1.MoveNext();
            bool enum2valid = enum2.MoveNext();
            while (enum1valid && enum2valid)
            {
                int cmpResult = cmp.Compare(enum1.Current, enum2.Current);
                if (cmpResult < 0)
                {
                    yield return enum1.Current;
                    enum1valid = enum1.MoveNext();
                }
                else if (cmpResult > 0)
                {
                    yield return enum2.Current;
                    enum2valid = enum2.MoveNext();
                }
                else
                {
                    enum1valid = enum1.MoveNext();
                    enum2valid = enum2.MoveNext();
                }
            }
            while (enum1valid)
            {
                yield return enum1.Current;
                enum1valid = enum1.MoveNext();
            }
            while (enum2valid)
            {
                yield return enum2.Current;
                enum2valid = enum2.MoveNext();
            }
        }
    }


    public static IEnumerable<T> SymmetricDifference<T>(IEnumerable<T> coll1, IEnumerable<T> coll2)
    {
        return SymmetricDifference(coll1, coll2, Comparer<T>.Default);
    }