我知道如何使用匿名类型按固定的值列表进行分组。我想要做的是按一组实际值分组。
例如,这个表达式的结果是 2。
new List<HashSet<int>> {
new HashSet<int> { 4 },
new HashSet<int> { 4 }
}.GroupBy (x => x).Count()
我正在寻找一种将这些集合放在同一组中的方法,以便结果为 1。在 python 中,这将使用frozenset
.
这样做最干净的方法是什么?
HashSet<T>.CreateSetComparer
您可以为此目的使用静态方法。
返回值
类型:System.Collections.Generic.IEqualityComparer> 一个 IEqualityComparer 对象,可用于 HashSet 对象的深度相等性测试。
new List<HashSet<int>> {
new HashSet<int> { 4 },
new HashSet<int> { 4 }
}.GroupBy (x => x, HashSet<int>.CreateSetComparer())
(我假设您想将两个集合分组为“相等”——这个问题不是很清楚)
与 LINQ 的情况一样,实现这一点的脚手架已经存在,需要做的是为IEqualityComparer<T>
适当的方法提供自定义。在这种情况下,这意味着使用这个重载。
这是一个泛型IEqualityComparer<ISet<T>>
,如果它们的交集与它们的交集相同,则声明两个集合相等:
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's just fine.
return set.Count;
}
}
以下是您如何将这两个集合分组在同一个保护伞下:
new List<HashSet<int>> {
new HashSet<int> { 4 },
new HashSet<int> { 4 }
}.GroupBy (x => x, new SetComparer<int>()).Count();
var result=new HashSet<int> { 4 }.Union(new HashSet<int> { 4 }).Count();