如何在C#中获取两个字符串数组之间的差异?

24

如何使用C#.net比较两个字符串数组? 示例:

string[] com1 = { "COM6", "COM7" };
string[] com2 = { "COM6", "COM7","COM8" };

这里的com1和com2是字符串数组。 结果为: COM8. 如何实现?


9
如果您能提供更多有关您想进行的比较的具体细节,那将非常有帮助。例如,您是否认为顺序很重要?大小写?如果一个元素出现在 com1 中但未出现在 com2 中怎么办? - Jon Skeet
6个回答

57

听起来你想要array2里面的所有东西,除了array1里面的内容:

var onlyInArray2 = array2.Except(array1);

当然,如果你还想知道只存在于array1中的内容,你可以使用以下代码:

var onlyInArray1 = array1.Except(array2);

这一切需要 .NET 3.5 或更高版本,或者使用 LINQBridge 等替代的LINQ to Objects 实现。

我假设在计算差异时顺序并不重要 - Except 是一个基于集合的运算符,所以它认为您将集合视为集合。

请注意,Except 只返回一个 IEnumerable<T> - 如果您想要将结果作为数组返回,您需要调用 ToArray

var onlyInArray2 = array2.Except(array1).ToArray();
var onlyInArray1 = array1.Except(array2).ToArray();

如果你想要对称差集,也就是只关心数组中有哪些值,而不关心它们来自哪个数组,你可以使用:

var onlyInOneArray = array1.Union(array2).Except(array1.Intersect(array2));

或者您可以直接使用 HashSet

var set = new HashSet<string>(array1);
// This modifies the set...
set.SymmetricExceptWith(array2);
在所有这些情况下,结果顺序是未定义的,尽管在实践中,Except将保留第一个参数的原始顺序。虽然严格来说这是一项实现细节,但我认为它很不可能发生变化。
像LINQ中的其他基于集合的运算符一样,Except只会返回任何元素一次 - 因此,如果array2中出现了两次COM8,它在结果中只会出现一次。

1
尊贵的Jon陛下,总是不断地添加更多的东西;-) - aleroot
2
我认为如果你在这里提供更好的答案,你可以再写一本书……我肯定会买! - aleroot

19

使用 Linq Except 扩展方法:

IEnumerable<string> result = com2.Except(com1); 
// result: { "COM8" }

建议:将 result 更改为 except(或者反过来) - default

10

7
我认为这是解决问题的最短途径。
foreach (string com in com2 )
{
    if (!com1.Contains(com))
    {
        MessageBox.Show(com);
    }
}

3

如果你想要一个表中的所有内容,但不包括另一个表中的内容,并且希望在一个表达式中实现,你可以使用 UnionIntersect Except

var inOnlyOneArray = array1.Union(array2).Except(array1.Intersect(array2));

+,那个真聪明! - user57508

1

正如其他人已经说过的那样,Except扩展方法绝对是这里应该采用的方式。然而,我要补充的是,看起来你可能想要一些控制比较方式的方法;如果'COM8'是一个串行端口标识符,则需要执行不区分大小写的比较:

var result = com2.Except(com1, StringComparer.OrdinalIgnoreCase);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接