【问题标题】:Is it possible to GroupBy a set of values using linq?是否可以使用 linq 对一组值进行分组?
【发布时间】:2012-08-02 15:19:02
【问题描述】:

我知道如何使用匿名类型按固定的值列表进行分组。我想做的是按一组实际值分组。

例如,这个表达式的结果是2。

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

我正在寻找一种将这些集合放在同一组中的方法,以便结果为 1。在 python 中,这将使用frozenset 来完成。

这样做最干净的方法是什么?

【问题讨论】:

  • 您不想分组。您需要使用 SelectMany
  • 所以你希望这个表达式的结果是 1?
  • 您是想将散列集中的元素组合成一个散列集,还是要组合所有相似的散列集?这里的区别不是很清楚。如果您想将所有哈希集组合成一个,请使用@AmiramKorach 指出的SelectMany。如果要按哈希集本身进行分组,则需要为 Hashset 提供 IEqualityComparer 实现:msdn.microsoft.com/en-us/library/bb534334
  • @AmiramKorach:我没有尝试计算联合,而是尝试通过基于哈希集的键对一组对象进行分组。感谢大家的投入。 HashSet&lt;T&gt;.CreateSetComparer 正是我想要的。

标签: c# linq group-by hashset


【解决方案1】:

您可以为此目的使用静态HashSet&lt;T&gt;.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())

【讨论】:

  • +1 因为每天都有新的东西要学习... :) 我想知道为什么他们认为内置这个是值得的。
【解决方案2】:

(我假设您想将两个集合分组为“相等”——这个问题不是很清楚)

与 LINQ 的常见情况一样,实现这一点的脚手架已经存在,需要做的是为适当的方法提供自定义 IEqualityComparer&lt;T&gt;。在这种情况下,这意味着使用this overload

这是一个通用的IEqualityComparer&lt;ISet&lt;T&gt;&gt;,如果它们的交集与它们的交集相同,则声明两个集合相等:

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();

【讨论】:

  • Downvoter:请通过发表评论帮助我改进此答案。谢谢。
  • 比较器的 Equals 方法,就目前而言,是不正确的。来自Except 文档:“此方法首先返回那些未出现在第二个中的元素。它确实还返回第二个中未出现在第一个中的那些元素。”我会改用ISet&lt;T&gt;.SetEquals
  • @Ani:哎呀。感谢您的提醒,已修复。
【解决方案3】:
var result=new HashSet<int> { 4 }.Union(new HashSet<int> { 4 }).Count();

【讨论】:

  • 这只是计算两组共有值的数量。它可能是可以使用的东西的基础,但我的问题是关于按集合对元素进行分组。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-11-08
  • 1970-01-01
  • 2011-03-16
  • 2017-05-02
  • 1970-01-01
  • 2016-04-09
  • 1970-01-01
相关资源
最近更新 更多