从通用列表中获取对称差异

时间:2009-11-05 19:59:05

标签: c# .net generics

我有2个单独的List,我需要比较两个并获取所有这两个列表的交集。我该怎么做(C#)?

7 个答案:

答案 0 :(得分:37)

如果你的意思是除了交点(对称差异)之外的所有东西,你可以尝试:

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

答案 1 :(得分:16)

您可以使用Except获取除两个列表中交叉点之外的所有内容。

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

如果您想获得除联盟之外的所有内容:

var allButUnion = new List<MyClass>();

(联盟是两个列表中的所有东西 - 除了联合之外的所有东西都是空集......)

答案 2 :(得分:7)

你的意思是只在一个列表中的所有内容吗?怎么样:

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

这可能有些低效,但它只是简单地表明你的意思(假设我当然正确地解释了你)。

答案 3 :(得分:1)

这样的东西?

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();

答案 4 :(得分:1)

这是一个通用的扩展方法。 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));
    }
}

我还没有真正对它进行基准测试。我认为这将取决于Union与Concat的实施方式。在我的梦幻世界中,.NET根据数据类型或集合大小使用不同的算法,但对于IEnumerable,它无法提前确定集合大小。

另外,你几乎可以忽略我的回答 - Jon Skeet说HashSet方法&#34;非常好 - 这看起来是对我这样做的最佳方式。&#34;

答案 5 :(得分:0)

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

答案 6 :(得分:-1)

使用例外:

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);