Получите симметричное отличие от общих списков

У меня есть 2 отдельных списка, и мне нужно сравнить их и получить все, кроме пересечения двух списков. Как я могу это сделать (С#)?

Ответ 1

Вы можете использовать Except, чтобы получить все, кроме пересечения двух списков.

var differences = listA.Except(listB).Union(listB.Except(listA));

Если вы хотите получить все, кроме union:

var allButUnion = new List<MyClass>();

(Объединение - это все в обоих списках - все, кроме объединения, - это пустой набор...)

Ответ 2

Если вы имеете в виду множество всего, кроме пересечения (симметричную разницу), вы можете попробовать:

var set = new HashSet<Type>(list1);
set.SymmetricExceptWith(list2);

Ответ 3

Вы имеете в виду все, что только в одном списке или другом? Как насчет:

var allButIntersection = a.Union(b).Except(a.Intersect(b));

Вероятно, это будет несколько неэффективно, но это довольно просто означает, что вы имеете в виду (предполагая, что я правильно интерпретировал вас).

Ответ 4

Что-то вроде этого?

String[] one = new String[] { "Merry", "Metal", "Median", "Medium", "Malfunction", "Mean", "Measure", "Melt", "Merit", "Metaphysical", "Mental", "Menial", "Mend", "Find" };
            String[] two = new String[] { "Merry", "Metal", "Find", "Puncture", "Revise", "Clamp", "Menial" };

List<String> tmp = one.Except(two).ToList();
tmp.AddRange(two.Except(one));

String[] result = tmp.ToArray();

Ответ 5

Вот общий метод расширения. Rosetta Code использует Concat, и Djeefther Souza говорит, что он более эффективен.

public static class LINQSetExtensions
{
    // Made aware of the name for this from Swift
    // https://stackoverflow.com/questions/1683147/get-the-symmetric-difference-from-generic-lists
    // Generic implementation adapted from https://www.rosettacode.org/wiki/Symmetric_difference
    public static IEnumerable<T> SymmetricDifference<T>(this IEnumerable<T> first, IEnumerable<T> second)
    {
        // I've used Union in the past, but I suppose Concat works. 
        // No idea if they perform differently. 
        return first.Except(second).Concat(second.Except(first));
    }
}

Я на самом деле не сравнивал это. Я думаю, что это будет зависеть от того, как реализованы союз против Concat. В моем dreamworld.NET использует другой алгоритм в зависимости от типа данных или заданного размера, хотя для IEnumerable он не может заранее определить размер набора.

Кроме того, вы можете в значительной степени игнорировать мой ответ - Джон Скит говорит, что метод HashSet "Отлично - это выглядит как лучший способ сделать это для меня".

Ответ 6

Использовать исключение:

List<int> l1 = new List<int>(new[] { 1, 2, 3, 4 });
List<int> l2 = new List<int>(new[] { 2, 4 });
var l3 = l1.Except(l2);

Ответ 7

var theUnion = list1.Concat(list2);
var theIntersection = list1.Intersect(list2);
var theSymmetricDifference = theUnion.Except(theIntersection);