Intersect可以用来查找两个集合之间的匹配,如下所示:

// Assign two arrays.
int[] array1 = { 1, 2, 3 };
int[] array2 = { 2, 3, 4 };
// Call Intersect extension method.
var intersect = array1.Intersect(array2);
// Write intersection to screen.
foreach (int value in intersect)
{
    Console.WriteLine(value); // Output: 2, 3
}

然而,我想实现的是相反的,我想从一个集合中列出从另一个集合中缺失的项目:

// Assign two arrays.
int[] array1 = { 1, 2, 3 };
int[] array2 = { 2, 3, 4 };
// Call "NonIntersect" extension method.
var intersect = array1.NonIntersect(array2); // I've made up the NonIntersect method
// Write intersection to screen.
foreach (int value in intersect)
{
    Console.WriteLine(value); // Output: 4
}

当前回答

这段代码只枚举每个序列一次,并使用Select(x => x)隐藏结果,以获得一个干净的linq风格的扩展方法。由于它使用哈希集<T>,如果哈希分布良好,它的运行时间为O(n + m)。两个列表中的重复元素将被省略。

public static IEnumerable<T> SymmetricExcept<T>(this IEnumerable<T> seq1,
    IEnumerable<T> seq2)
{
    HashSet<T> hashSet = new HashSet<T>(seq1);
    hashSet.SymmetricExceptWith(seq2);
    return hashSet.Select(x => x);
}

其他回答

我想你可能在找除了:

Except操作符生成集合 两个序列之间的差异。它 只返回第一个中的元素 中未出现的序列 第二。您可以选择提供 你自己的相等比较函数。

查看这个链接,这个链接,或者谷歌,获取更多信息。

array1.NonIntersect (array2);

不相交这样的运算符在Linq中是不存在的你应该做的

Except -> union -> Except

a.except(b).union(b.Except(a));

我不是100%确定你的非相交方法应该做什么(关于集合论)-是吗 B \ A(所有来自B而不在A中出现的东西)? 如果是,那么您应该能够使用Except操作(B.Except(A))。

如上所述,如果你想要得到4作为结果,你可以这样做:

var nonintersect = array2.Except(array1);

如果你想要真正的非交集(也是1和4),那么这个应该可以做到:

var nonintersect = array1.Except(array2).Union( array2.Except(array1));

这不是性能最好的解决方案,但对于小列表来说,它应该工作得很好。

这段代码只枚举每个序列一次,并使用Select(x => x)隐藏结果,以获得一个干净的linq风格的扩展方法。由于它使用哈希集<T>,如果哈希分布良好,它的运行时间为O(n + m)。两个列表中的重复元素将被省略。

public static IEnumerable<T> SymmetricExcept<T>(this IEnumerable<T> seq1,
    IEnumerable<T> seq2)
{
    HashSet<T> hashSet = new HashSet<T>(seq1);
    hashSet.SymmetricExceptWith(seq2);
    return hashSet.Select(x => x);
}