C# 比较两个数组并返回不重复项的多种方法
本文将介绍在 C# 中如何高效地比较两个数组或列表,并提取出仅存在于其中一个集合中的元素(即对称差集或相对补集),涵盖从基础循环到现代 LINQ 语法的多种实现方案。
需求场景
假设你有两组字符串数据:
- Ashuzu: 包含 "1", "2", "3"
- Bshuzu: 包含 "1", "2", "4"
Ashuzu 中移除那些也出现在 Bshuzu 中的元素,从而得到仅属于 A 的差异部分(本例中预期结果为 "3")。
方法一:传统 foreach 循环
这是最直观的逻辑实现,通过遍历每个元素并检查是否存在于另一个列表中,将唯一元素添加到新列表。虽然逻辑清晰,但在大数据量下性能较差,因为 List.Contains() 的时间复杂度为 O(n)。
List<string> Ashuzu = new List<string>();
Ashuzu.Add("1");
Ashuzu.Add("2");
Ashuzu.Add("3");
List<string> Bshuzu = new List<string>();
Bshuzu.Add("1");
Bshuzu.Add("2");
Bshuzu.Add("4");
List<string> Cshuzu = new List<string>();
// 目的:从 Ashuzu 中剔除 Bshuzu 存在的元素
foreach (string aitem in Ashuzu)
{
if (!Bshuzu.Contains(aitem))
{
Cshuzu.Add(aitem);
}
}
// 此时 Cshuzu 包含: ["3"]
方法二:使用 LINQ Except(推荐)
LINQ 提供了更声明式的写法。Except 方法会自动处理去重并返回第一个序列中不在第二个序列中出现的所有元素。它不仅代码简短,而且底层通常针对性能做过优化。
var result = Ashuzu.Except(Bshuzu).ToList(); // 结果同样为 ["3"]
方法三:使用 HashSet(高性能去重)
如果需要频繁进行查找操作,或者数据量极大,推荐使用 HashSet。它将查找时间复杂度降低至 O(1)。这种方式适合需要对大量数据进行复杂集合运算的场景。
var hashA = new HashSet<string>(Ashuzu); hashA.ExceptWith(Bshuzu); // 在原地修改 hashA,移除存在于 Bshuzu 的元素 var result = hashA.ToList(); // 结果: ["3"]
注意事项
- 大小写敏感:上述默认实现区分大小写。如果字符串内容相同但大小写不同被视为重复,需传入
StringComparer.OrdinalIgnoreCase等比较器。 - null 值处理:
List和HashSet均能容纳 null 值,但在使用 LINQExcept时需注意引用类型的空指针风险(尽管 string 为引用类型但内部实现了安全比较)。 - 返回值语义:
Except类似于数学上的“差集”(A - B),如果你需要的是“对称差集”(即在 A 中但不在 B,或在 B 中但不在 A 的所有元素),则需要额外组合 LINQ 查询。
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









