C# 合并 2 个集合的不同项
本文关键字:集合 合并 | 更新日期: 2023-09-27 17:56:26
我正在寻找一种高性能的方式来将第二个 ICollection 的不同项目添加到现有项目。我正在使用 .NET 4。
这应该可以做到:
list1.Union(list2).Distinct(aCustomComparer).ToList()
只要它们是 IEnumerable,您就可以使用 go-to Linq 答案:
var union = firstCollection.Union(secondCollection);
这将使用默认的相等比较,对于大多数对象,这是参照相等。若要更改此设置,可以为集合中的项类型定义一个 IEqualityComparer 泛型,该泛型将执行更语义的比较,并将其指定为联合的第二个参数。
添加到现有列表中的另一种方法是:
list1.AddRange(list2.Distinct().Except(list1));
对你的问题最直接的答案 - 因为你没有给出太多关于你作为输入或需要作为输出的实际ICollection类型的细节,所以KeithS给出的答案是KeithS给出的
答案。var union = firstCollection.Union(secondCollection);
这将返回一个不同的 IEnumerable - 如果这是你需要的,那么它非常快。 我制作了一个小型测试应用程序(下图),它针对一个简单的重复数据删除哈希集方法运行联合方法(MethodA),并返回一个Hashset<>(MethodB)。 联合方法销毁哈希集:
方法A:1ms
方法B:2827ms
但是 - 必须将该IEnumerable转换为其他类型的集合,例如List<>(如ADas发布的版本)会更改所有内容:
只需添加 .ToList() 到 MethodA
var union = firstCollection.Union(secondCollection).ToList();
更改结果:
方法A:3656ms
方法B:2803ms
所以 - 似乎需要更多地了解您正在使用的特定案例 - 并且您提出的任何解决方案都应该进行测试 - 因为一个小的(代码)更改可能会产生巨大的影响。
以下是我用来比较这些方法的测试 - 我确信这是一种愚蠢的测试方法 - 但它似乎有效:)
private static void Main(string[] args)
{
ICollection<string> collectionA = new List<string>();
ICollection<string> collectionB = new List<string>();
for (int i = 0; i < 1000; i++)
{
string randomString = Path.GetRandomFileName();
collectionA.Add(randomString);
collectionA.Add(randomString);
collectionB.Add(randomString);
collectionB.Add(randomString);
}
Stopwatch testA = new Stopwatch();
testA.Start();
MethodA(collectionA, collectionB);
testA.Stop();
Stopwatch testB = new Stopwatch();
testB.Start();
MethodB(collectionA, collectionB);
testB.Stop();
Console.WriteLine("MethodA: {0}ms", testA.ElapsedMilliseconds);
Console.WriteLine("MethodB: {0}ms", testB.ElapsedMilliseconds);
Console.ReadLine();
}
private static void MethodA(ICollection<string> collectionA, ICollection<string> collectionB)
{
for (int i = 0; i < 10000; i++)
{
var result = collectionA.Union(collectionB);
}
}
private static void MethodB(ICollection<string> collectionA, ICollection<string> collectionB)
{
for (int i = 0; i < 10000; i++)
{
var result = new HashSet<string>(collectionA);
foreach (string s in collectionB)
{
result.Add(s);
}
}
}