C# 中的 HashSet 是不是有等效的 AddRange
Posted
技术标签:
【中文标题】C# 中的 HashSet 是不是有等效的 AddRange【英文标题】:Is there an AddRange equivalent for a HashSet in C#C# 中的 HashSet 是否有等效的 AddRange 【发布时间】:2013-02-22 09:44:41 【问题描述】:有了一个列表,你可以做到:
list.AddRange(otherCollection);
HashSet
中没有添加范围方法。
将另一个 ICollection
添加到 HashSet
的最佳方法是什么?
【问题讨论】:
【参考方案1】:对于HashSet<T>
,名称为UnionWith
。
这是为了表明HashSet
的独特工作方式。你不能像Collections
那样安全地给Add
一组随机元素,有些元素可能会自然蒸发。
我认为UnionWith
在“与另一个HashSet
合并”之后得名,但是IEnumerable<T>
也有过载。
【讨论】:
恕我直言,HashSet
(和ISet
)是用数学设定的术语创建的。 UnionWith
是最近的术语。除了Except
,在数学上显然应该命名为Subtract
。【参考方案2】:
这是一种方式:
public static class Extensions
public static bool AddRange<T>(this HashSet<T> source, IEnumerable<T> items)
bool allAdded = true;
foreach (T item in items)
allAdded &= source.Add(item);
return allAdded;
【讨论】:
这可能存在性能问题,因为哈希集将在每次迭代时重新排序。【参考方案3】:您也可以将CONCAT 与 LINQ 一起使用。这会将一个集合或特别是 HashSet<T>
附加到另一个集合上。
var A = new HashSet<int>() 1, 2, 3 ; // contents of HashSet 'A'
var B = new HashSet<int>() 4, 5 ; // contents of HashSet 'B'
// Concat 'B' to 'A'
A = A.Concat(B).ToHashSet(); // Or one could use: ToList(), ToArray(), ...
// 'A' now also includes contents of 'B'
Console.WriteLine(A);
>>>> 1, 2, 3, 4, 5
注意: Concat()
创建一个全新的集合。此外,UnionWith()
比 Concat() 更快。
"... this (Concat()
) 还假设您实际上可以访问引用哈希集的变量并允许对其进行修改,但情况并非总是如此。" – @彼得杜尼霍
【讨论】:
确实,您可以使用Concat()
。但这样做比仅仅调用为该目的设计的UnionWith()
方法差100%,正如公认的答案所建议的那样。请注意,这还假设您实际上可以访问引用散列集的变量并允许对其进行修改,但情况并非总是如此。
@PeterDuniho 我认为 Concat() 比使用 Add() 单独添加每个元素的 RoadieRich 解决方案更容易使用。此外,要使用他的解决方案,必须复制并粘贴他的代码块才能使用他的解决方案。我的解决方案虽然不是最好的,但比 RoadieRich 解决方案要苗条得多。不过,你的推理很好理解。
“我认为 Concat() 会比 RoadieRich 使用 Add() 单独添加每个元素的第二个答案更快” - 你为什么会这样认为?您的示例创建了 三个 新对象(两个迭代器和一个新的 HashSet<T>
),并且必须从头开始填充第三个对象,而迭代地调用 Add()
不会创建新对象,只需添加实际上是新的元素。我怀疑你的提议比内置的UnionWith()
方法或在另一个答案中提出的扩展方法更有效。
“一个人必须复制和粘贴他的代码块”——他们不必这样做才能使用你的代码?无论如何,复制/粘贴并不是一个重要的问题,但这并不意味着您的代码会神奇地传输到其他人的项目中。它要么必须被复制和粘贴,要么也必须重新输入。
再一次,您的示例要求可以用新的集合实际替换现有集合,这实际上并不总是正确的,并且在任何情况下都与解决方案等效到AddRange()
的原始要求有很大不同。该问题专门要求“将另一个ICollection
添加到HashSet
”,但您提出的解决方案根本没有这样做;相反,它会创建一个全新的HashSet<T>
。以上是关于C# 中的 HashSet 是不是有等效的 AddRange的主要内容,如果未能解决你的问题,请参考以下文章
C# 中是不是有 .isConnected 功能的 python 等效项
如何从 C# 中的方法返回等效的 VB6 Variant 类型
怎样在C#中把0-10这11个数随机顺序不重复的放到集合里面?