C#中是否有HashSet的AddRange等效方法?

455

使用列表可以做到:

list.AddRange(otherCollection);

HashSet 中没有添加范围的方法。 最好的方法是如何将另一个 ICollection 添加到 HashSet 中?

3个回答

820
对于HashSet<T>,名称为UnionWith
这是为了表明HashSet的独特工作方式。您不能像在Collections中那样安全地将一组随机元素添加到其中,因为某些元素可能会自然蒸发。
我认为UnionWith的命名来自“与另一个HashSet合并”,但是也有一个IEnumerable<T>的重载。

16
在我看来,HashSet(和ISet)是以数学集合术语创建的。 UnionWith 是较接近的术语。除了 Except 外,从数学角度讲,显然应该将其命名为 Subtract - fa wildchild

10
这是一种方法:
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;
    }
}

这可能会存在性能问题,因为哈希集合将在每次迭代时被重新排序。 - Jacob Stamm
2
什么是替代方案?UnionWith 做的事情完全一样。 - Albert Hoekstra

6
你还可以在 LINQ 中使用 CONCAT。这将把一个集合,或者具体地说,一个 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() 更快。

"...这也假设您实际上可以访问引用哈希集的变量并被允许修改它,但这并不总是情况。"- @PeterDuniho


3
没错,你_可以_使用Concat()。但这样做比调用专门为此目的设计的UnionWith()方法要差100%,正如所提供的答案建议的那样。请注意,这也假定您实际上可以访问引用哈希集的变量并且被允许修改它,这并不总是情况。 - Peter Duniho
@PeterDuniho 我认为使用Concat()比使用RoadieRich的解决方案逐个添加每个元素更容易。此外,要使用他的解决方案,你甚至需要复制和粘贴他的代码块才能使用他的解决方案。我的解决方案虽然不是最好的,但比RoadieRich的解决方案要轻巧得多。不过,你的想法非常易懂。 - Andrew
“我认为使用Concat()比RoadieRich的第二个答案逐个添加每个元素要快” - 你为什么会这样认为呢?你的示例创建了三个新对象(两个迭代器和一个新的HashSet<T>),并且必须从头开始填充第三个对象,而调用Add()迭代地创建没有新对象,只需要添加实际上是新的元素。我怀疑你的建议比内置的UnionWith()方法或其他答案中提出的扩展方法更高效。 - Peter Duniho
1
再次强调,你的例子要求实际上必须能够用新的集合_替换_现有的集合,这并不总是正确的,而且无论如何都与最初的要求相去甚远,即解决方案应该等同于AddRange()。问题明确要求将另一个ICollection添加到HashSet中,然而你提出的解决方案根本没有做到这一点;相反,它创建了一个全新的HashSet<T> - Peter Duniho
@PeterDuniho,您建议我删除我的回答吗? - Andrew
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接