我正在尋找一種高性能的方法來將第二個ICollection的不同項目添加到現有的項目中。我使用.NET 4C#合併2個集合的不同項目
回答
這應做到:
list1.Union(list2).Distinct(aCustomComparer).ToList()
只要他們IEnumerable的,你可以使用去到Linq的答案:
var union = firstCollection.Union(secondCollection);
這將使用默認的相等比較,這對於大多數對象來說是引用相等。爲了改變這種情況,您可以爲集合中的項目類型定義一個IEqualityComparer泛型,以執行更多的語義比較,並將其指定爲聯盟的第二個參數。
另一種方式添加到您的exisiting名單將是:
list1.AddRange(list2.Distinct().Except(list1));
這基本上是Union(),BTW背後的操作。 Except()迭代器將基本上在傳遞的list1上調用Any(x => x == Current),並從list2返回它爲false的項目。 – KeithS
除聯盟不修改原始列表外,OP要求'將第二個ICollection的不同項目添加到現有列表',聯盟返回一個新的集合。 –
我的答案可能不是OP想要的,但是他的問題可能是模棱兩可的。 –
最直接的回答你的問題 - 因爲你沒有實際類型的ICollection的你必須爲輸入或需要提供多少細節作爲輸出是KeithS
var union = firstCollection.Union(secondCollection);
給出的這將返回一個不同的IEnumerable - 如果這是你需要的話,就非常快。我製作了一個運行聯合方法(MethodA)的小測試應用程序(MethodA),該應用程序針對重複數據刪除的簡單哈希集方法,並返回一個Hashset(MethodB)。工會法破壞了HashSet的:
治法:1毫秒
方法b:2827ms
然而 - 有到了IEnumerable轉換爲其他類型的集合如List <>(如發佈版本ADAS)改變了一切:
簡單地增加.ToList()來治法
var union = firstCollection.Union(secondCollection).ToList();
改變的結果:
治法: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);
}
}
}
只是要清楚;總是比Linq有更高性能的解決方案。然而,對於你在.NET中開始編程的99.9%(與更多的本地語言相比,它會將任何.NET實現排除在外),Linq在性能方面表現良好,並且通常更易於理解和執行。 – KeithS
MethodA更快的原因是因爲它沒有枚舉它返回的集合的元素,這就是調用ToList的原因使它慢得多。 –
- 1. C#集合結合項目
- 2. 合併2個集合
- 3. 合併TFS團隊項目集合
- 4. 合併2個流星JS項目
- 5. 如何合併列表中的項目<>集合C#
- 6. 將不同的Maven Web項目合併到一個項目中
- 7. SVN將不同的項目合併成一個主項目
- 8. 合併2個集,laravel
- 9. Maven android-合併不同的android項目
- 10. 比較集合不同項目類型
- 11. 合併C#項目的兩個版本
- 12. 合併2個ResultSet的不同領域
- 13. 合併兩個集合,總結等領域的重複項目
- 14. 在複合集合中插入不同的項目類型
- 15. 如何合併2個不同長度的數據集?
- 16. C#合併2個報告
- 17. C#合併2個字典
- 18. 合併項目
- 19. pyspark - 合併2列的集合
- 20. 使用LINQ合併項目在一個集合
- 21. 如何整合來自2個不同項目的Spring和GWT
- 22. 我們可以合併GIT中的2個不同項目的分支
- 23. 添加項目到集合集合
- 24. C#集合的項目到期
- 25. 合併多個SVN項目
- 26. 合併兩個laravel項目
- 27. 合併兩個VB.Net項目
- 28. 合併兩個android項目
- 29. 合併多個JSF項目
- 30. 合併兩個Maven項目?
是不是多餘的使用distinct()在Union()之後? – 0xbadf00d
取決於工會的條件。默認情況下,Union()方法只會對具有相同引用的對象進行重複數據刪除。由於Distinct使用自定義的IEqualityComparer,因此它實際上會做比聯合更多的事情。但是,IEqualityComparer也可以直接作爲聯盟使用,因此它有點多餘 – KeithS
Union使用默認的相等比較器,根據類型的不同,它可能是也可能不是參考比較器。請參閱https://msdn.microsoft.com/en-us/library/vstudio/bb341731(v=vs.100).aspx和https://msdn.microsoft.com/en-us/library/vstudio/bb341731( v = VS.100)的.aspx。此外,正如你所提到的那樣,最好將自定義比較器提供給'Union'方法,並且爲了可讀性和(可能)略微提高性能而取消「Distinct」調用。 –