tags:

views:

82

answers:

3

I've got a HashSet,

var universe = new HashSet<int>();

And a bunch of subsets,

var sets = new List<HashSet<int>>(numSets);

I want to subtract a chunk,

var remaining = universe.ExceptWith(sets[0]);

It looks like ExceptWith is the function I want, but it works in-place. I don't want to modify the universe... I guess I should clone it first? How do I do that?

+5  A: 

How about Except()?

var x = new HashSet<int>();
var y = new HashSet<int>();

var xminusy = new HashSet<int>(x.Except(y));
James McNellis
But `Except` is an extension method, `ExceptWith` is specifically built to work with `HashSets`... is this just as efficient?
Mark
@Mark, it's definitely less efficient than *just* `ExceptWith`, but it's about as efficient as *cloning* it first and then calling `ExceptWith`.
Kirk Woll
+2  A: 

I guess I should clone it first? How do I do that?

var universe = new HashSet<int>();
var subset = new HashSet<int>();
...

// clone the universe
var remaining = new HashSet<int>(universe);
remaining.ExceptWith(subset);

Not as simple as with the Except extension method, but probably faster (you should run a few performance tests to make sure)

Thomas Levesque
+1  A: 

A hash set has to track its hash algorithm constants, and its overflow bins. The elements in the set are held by reference. Creating a new hash with the copy constructor, as Thomas Levesque suggests, creates a shallow copy of this overhead and should be quite fast. Using Except() in the way that James McNellis suggests first creates an anonymous copy and then passes that to the copy constructor which uses the fields in the anonymous to initialize its own fields. As Thomas said, you might do a few performance tests, but theoretically his answer should beat James' answer. And by the way, to my way of thinking, a shallow copy is not a clone since I believe a clone implies that the underlying elements are also copied. Hash sets with common elements use a copy when modified strategy.

verisimilidude
Yeah.. you're right, I don't think I need a deep copy anyway. Using int's in this example, but they'll be classes in practice; a reference is fine though.
Mark