Best to demonstrate what some of the methods do with some unit tests. In particular what does 'SymmetricExceptWith' do?
Here are some extension methods that maintain the original values of the sets (the existing methods modify the calling set)
[ TestFixture ]
public class HashSetTests
{
private HashSet<int> integerSet1;
private HashSet<int> integerSet1Copy;
private HashSet<int> integerSet2;
[ SetUp ]
public void Setup()
{
integerSet1 = new HashSet<int> { 1, 2, 3 };
integerSet2 = new HashSet<int> { 2, 3, 4 };
integerSet1Copy = new HashSet<int> { 2, 3, 1 };
}
[ Test ]
// The SetEquals method ignores duplicate entries and
// the order of elements in the other parameter.
public void SetEqualsTest()
{
var integerList = new List<int> { 2, 3, 1, 3, 2 };
Assert.That( !integerSet1.SetEquals( integerSet2 ) );
Assert.That( integerSet1.SetEquals( integerSet1Copy ) );
Assert.That( integerSet1.SetEquals( integerList ) );
}
[ Test ]
public void IntersectWithTest() // All elements common to both sets
{
integerSet1.IntersectWith( integerSet2 );
Assert.That( !integerSet1.Contains( 1 ) );
Assert.That( integerSet1.Contains( 2 ) );
Assert.That( integerSet1.Contains( 3 ) );
Assert.That( !integerSet1.Contains( 4 ) );
}
[ Test ]
public void UnionWithTest() // All elements in both sets
{
integerSet1.UnionWith( integerSet2 );
Assert.That( integerSet1.Contains( 1 ) );
Assert.That( integerSet1.Contains( 2 ) );
Assert.That( integerSet1.Contains( 3 ) );
Assert.That( integerSet1.Contains( 4 ) );
}
[ Test ]
public void SymmetricExceptWithTest() // All elements not common to both sets
{
integerSet1.SymmetricExceptWith( integerSet2 );
Assert.That( integerSet1.Contains( 1 ) );
Assert.That( !integerSet1.Contains( 2 ) );
Assert.That( !integerSet1.Contains( 3 ) );
Assert.That( integerSet1.Contains( 4 ) );
}
}
Here are some extension methods that maintain the original values of the sets (the existing methods modify the calling set)
// Extensions Set operations that maintain the original values of the original sets
// Be aware that these can be expensive operations if the sets are very large
// I changed the names to make the operations easier to recognise
public static class HashSetExtensions
{
// A U B => Everything from set A and set B
public static HashSet<T> Union<T>(this HashSet<T> hashSet1, HashSet<T> hashSet2)
{
var res = new HashSet<T>(hashSet1, hashSet1.Comparer);
res.UnionWith(hashSet2);
return res;
}
// A ∩ B => Everything in both set A and set B
public static HashSet<T> Intersecting<T>(this HashSet<T> hashSet1, HashSet<T> hashSet2)
{
var res = new HashSet<T>(hashSet1, hashSet1.Comparer);
res.IntersectWith(hashSet2);
return res;
}
// A - B => Everything in set A minus anything in set B
public static HashSet<T> RemoveAnyFrom<T>(this HashSet<T> hashSet1, HashSet<T> hashSet2)
{
var res = new HashSet<T>(hashSet1, hashSet1.Comparer);
res.ExceptWith(hashSet2);
return res;
}
// A ∆ B => Equivalent to an XOR, also equivalent to NOT(A ∩ B)
public static HashSet<T> NotIntersecting<T>(this HashSet<T> hashSet1, HashSet<T> hashSet2)
{
var res = new HashSet<T>(hashSet1, hashSet1.Comparer);
res.SymmetricExceptWith(hashSet2);
return res;
}
}
and some tests for them
void Main()
{
string[] names1 = new string[] {
"banana","apple","pear","orange","grapes","mango"
};
string[] names2 = new string[] {
"advocado","lemon","pear","lime","banana","passion fruit"
};
HashSet<string> setA = new HashSet<string>(names1, StringComparer.OrdinalIgnoreCase);
HashSet<string> setB = new HashSet<string>(names2, StringComparer.OrdinalIgnoreCase);
var res1 = setA.Union(setB);
var res2 = setA.Intersecting(setB);
var res3 = setA.RemoveAnyFrom(setB);
var res4 = setA.NotIntersecting(setB);
Console.WriteLine("A = " + string.Join(", ", setA));
Console.WriteLine("B = " + string.Join(", ", setB));
Console.WriteLine("A U B = " + string.Join(", ", res1));
Console.WriteLine("A ∩ B = " + string.Join(", ", res2));
Console.WriteLine("A - B = " + string.Join(", ", res3));
Console.WriteLine("A ∆ B = " + string.Join(", ", res4));
}
which outputs to the console the following:
A = banana, apple, pear, orange, grapes, mango B = advocado, lemon, pear, lime, banana, passion fruit A U B = banana, apple, pear, orange, grapes, mango, advocado, lemon, lime, passion fruit A ∩ B = banana, pear A - B = apple, orange, grapes, mango A ∆ B = passion fruit, apple, lime, orange, grapes, mango, advocado, lemon
No comments:
Post a Comment