Can GroupBy use a value set using linq?

I know how you can use anonymous types to group by a fixed list of values. What I want to do is a group on the actual set of values.

For example, the result of this expression is 2.

new List<HashSet<int>> { new HashSet<int> { 4 }, new HashSet<int> { 4 } }.GroupBy (x => x).Count() 

I am looking for a way to place these groups in one group so that the result is equal to 1. In python, this will be done using frozenset .

What is the cleanest way to do this?

+8
c # linq group-by hashset
source share
3 answers

You can use the static HashSet<T>.CreateSetComparer method for this purpose.

Return value

Type: System.Collections.Generic.IEqualityComparer> An IEqualityComparer object that can be used for deep equality testing of a HashSet object.

 new List<HashSet<int>> { new HashSet<int> { 4 }, new HashSet<int> { 4 } }.GroupBy (x => x, HashSet<int>.CreateSetComparer()) 
+8
source share

(I assume that you want to group both sets as equals - the question is not very clear)

As is often the case with LINQ, scaffolding already exists for this, and what needs to be done is to provide a custom IEqualityComparer<T> appropriate method. In this case, this means this overload .

There is a generic IEqualityComparer<ISet<T>> that declares two sets equal if their intersection is the same as both of them:

 class SetComparer<T> : IEqualityComparer<ISet<T>> { public bool Equals(ISet<T> lhs, ISet<T> rhs) { // null checks omitted return lhs.SetEquals(rhs); } public int GetHashCode(ISet<T> set) { // Not the best choice for a hash function in general, // but in this case it just fine. return set.Count; } } 

And this is how you would group both sets under the same umbrella:

 new List<HashSet<int>> { new HashSet<int> { 4 }, new HashSet<int> { 4 } }.GroupBy (x => x, new SetComparer<int>()).Count(); 
+3
source share
 var result=new HashSet<int> { 4 }.Union(new HashSet<int> { 4 }).Count(); 
0
source share

All Articles