453

With a list you can do:

list.AddRange(otherCollection);

There is no add range method in a HashSet. What is the best way to add another ICollection to a HashSet?

Neuron
  • 5,141
  • 5
  • 38
  • 59
Stefanos Kargas
  • 10,547
  • 22
  • 76
  • 101

3 Answers3

809

For HashSet<T>, the name is UnionWith.

This is to indicate the distinct way the HashSet works. You cannot safely Add a set of random elements to it like in Collections, some elements may naturally evaporate.

I think that UnionWith takes its name after "merging with another HashSet", however, there's an overload for IEnumerable<T> too.

Neuron
  • 5,141
  • 5
  • 38
  • 59
quetzalcoatl
  • 32,194
  • 8
  • 68
  • 107
  • 16
    Imho, `HashSet` (and `ISet`) was created with mathematically set term. `UnionWith` was the nearer term. Except for `Except`, which clearly should be named as `Subtract`, mathematically speaking. – fa wildchild Jan 07 '15 at 03:39
9

This is one way:

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;
    }
}
mihkov
  • 1,171
  • 13
  • 37
RoadieRich
  • 6,330
  • 3
  • 35
  • 52
6

You can also use CONCAT with LINQ. This will append a collection or specifically a HashSet<T> onto another.

    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}

NOTE: Concat() creates an entirely new collection. Also, UnionWith() is faster than Concat().

"... this (Concat()) also assumes you actually have access to the variable referencing the hash set and are allowed to modify it, which is not always the case." – @PeterDuniho

Andrew
  • 129
  • 2
  • 8
  • 2
    It's true, you _could_ use `Concat()`. But doing so is 100% worse than just calling the `UnionWith()` method that was designed for the purpose, as the accepted answer proposes. Note that this also assumes you actually have access to the variable referencing the hash set and are allowed to modify it, which is not always the case. – Peter Duniho Jun 22 '21 at 23:58
  • @PeterDuniho I assume Concat() is easier utilized than RoadieRich solution of adding each element individually using Add(). Moreover, to use his solution, one would have to copy and paste his block of code to even utilize his solution. My solution, while it is not the best, is significantly slimmer than RoadieRich solution. However, your reasoning is very understandable. – Andrew Jun 23 '21 at 17:01
  • _"I assume Concat() would be faster than the second answer by RoadieRich of adding each element individually using Add()"_ -- why would you assume that? Your example creates **three** new objects (two iterators and a new `HashSet`), and has to populate that third object from scratch, while calling `Add()` iteratively creates no new objects, and only has to add the elements that are actually new. I doubt your proposal is more performant than the built-in `UnionWith()` method _or_ the extension method proposed in the other answer. – Peter Duniho Jun 23 '21 at 17:06
  • _"one would have to copy and paste his block of code"_ -- and they don't have to do so to use yours? Not that copy/paste is in any way a material concern anyway, but it's not like your code magically gets transported to someone else's project. It either has to be copied and pasted or retyped as well. – Peter Duniho Jun 23 '21 at 17:06
  • 1
    And again, your example _requires_ that it be possible to actually _replace_ the existing collection with a new one, something that is not actually always true, and in any case is a significant departure from the original requirement that the solution be **equivalent** to `AddRange()`. The question specifically ask to _"add another `ICollection` to a `HashSet`"_, and yet your proposed solution does not do that at all; instead, it creates a whole new `HashSet`. – Peter Duniho Jun 23 '21 at 17:07
  • _"... and they don't have to do so to use yours?"_ @PeterDuniho RoadieRich solution is 9 lines long, compared to my 1 line `A = A.Concat(B).ToHashSet()` using a LINQ function. My solution is pretty clean cut. How is 1 line the same as 9 lines using RoadieRich solution. I do understand you reasoning `UnionWith()` is a better suited solution. – Andrew Jun 23 '21 at 17:20
  • @PeterDuniho would you recommend my answer to be removed? – Andrew Jun 23 '21 at 17:22