C#合并2个集合的不同项
我正在寻找一种高效的方法来将第二个ICollection的不同项添加到现有的ICollection中。 我正在使用.NET 4。
这应该这样做:
list1.Union(list2).Distinct(aCustomComparer).ToList()
只要它们是IEnumerable,你就可以使用Linq的回答:
var union = firstCollection.Union(secondCollection);
这将使用默认的相等比较,对于大多数对象,它是引用相等。 要更改此设置,您可以为集合中的项类型定义IEqualityComparergenerics,以执行更多语义比较,并将其指定为Union的第二个参数。
添加到现有列表的另一种方法是:
list1.AddRange(list2.Distinct().Except(list1));
你问题最直接的答案 – 因为你没有详细说明你输入或需要输出的ICollection的实际类型是KeithS给出的
var union = firstCollection.Union(secondCollection);
这将返回一个独特的IEnumerable – 如果这是你需要的那么它非常快。 我做了一个小测试应用程序(下面),它针对重复数据删除的简单hashset方法运行union方法(MethodA)并返回一个Hashset <>(MethodB)。 联合方法DESTROYS的hashset:
方法A:1ms
方法B:2827ms
但是 – 必须将IEnumerable转换为其他类型的集合(如List <>(如发布的ADas版本))会更改所有内容:
只需将.ToList()添加到MethodA即可
var union = firstCollection.Union(secondCollection).ToList();
更改结果:
方法A:3656ms
方法B:2803毫秒
所以 – 似乎需要了解您正在使用的具体案例 – 并且应该测试您提出的任何解决方案 – 因为小的(代码)更改可能会产生巨大的影响。
下面是我用来比较这些方法的测试 – 我确定这是一种愚蠢的测试方法 – 但它似乎工作:)
private static void Main(string[] args) { ICollection collectionA = new List (); ICollection collectionB = new List (); 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 collectionA, ICollection collectionB) { for (int i = 0; i < 10000; i++) { var result = collectionA.Union(collectionB); } } private static void MethodB(ICollection collectionA, ICollection collectionB) { for (int i = 0; i < 10000; i++) { var result = new HashSet (collectionA); foreach (string s in collectionB) { result.Add(s); } } }