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&lt;T&gt; 附加到另一个集合上。

    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&lt;T&gt;),并且必须从头开始填充第三个对象,而迭代地调用 Add() 不会创建新对象,只需添加实际上是新的元素。我怀疑你的提议比内置的UnionWith() 方法在另一个答案中提出的扩展方法更有效。 “一个人必须复制和粘贴他的代码块”——他们不必这样做才能使用你的代码?无论如何,复制/粘贴并不是一个重要的问题,但这并不意味着您的代码会神奇地传输到其他人的项目中。它要么必须被复制和粘贴,要么也必须重新输入。 再一次,您的示例要求可以用新的集合实际替换现有集合,这实际上并不总是正确的,并且在任何情况下都与解决方案等效AddRange()的原始要求有很大不同。该问题专门要求“将另一个ICollection 添加到HashSet,但您提出的解决方案根本没有这样做;相反,它会创建一个全新的HashSet&lt;T&gt;

以上是关于C# 中的 HashSet 是不是有等效的 AddRange的主要内容,如果未能解决你的问题,请参考以下文章

C#中CreateObject的等效代码

C# 中是不是有 .isConnected 功能的 python 等效项

如何从 C# 中的方法返回等效的 VB6 Variant 类型

怎样在C#中把0-10这11个数随机顺序不重复的放到集合里面?

Qt 的 moc/C++11 是不是与 C# 的 nameof() 运算符等效?

C# 中的 Java Map 等效项