繁体   English   中英

LINQ Group通过收藏

[英]LINQ GroupBy collection

是否可以使用collection属性在LINQ中使用GroupBy?

例如

void Main()
{
    var t1 = new Test() { Children = new List<string>() { "one", "two" } };
    var t2 = new Test() { Children = new List<string>() { "one", "two" } };
    var t3 = new Test() { Children = new List<string>() { "one", "three" }        };

    var tests = new List<Test>() { t1, t2, t3 };
    var anon =  from t in tests
                select new
                {
                    Children = t.Children
                };

    anon.GroupBy(t => t.Children).Dump();
}

public class Test
{
    public List<string> Children {get;set;}
}

在此示例中,我希望有两个小组:

键:List(){“一个”,“两个”}值:t1,t2

键:List(){“一个”,“三个”}值:t3

我的理解是,匿名类型不是通过引用进行比较,而是通过比较其公共属性的相等性来进行比较。

但是,实际结果分为三组:

键:List(){“一个”,“两个”}值:t1

键:List(){“一个”,“两个”}值:t2

键:List(){“一个”,“三个”}值:t3

如果这不可能,有没有办法得到我想要的结果?

希望可以清楚地解释这一点...

默认情况下, GroupBy将在按列表分组(引用类型)时使用引用相等性。

由于您每次都有列表的新实例,因此它们是不相等的。

但是, GroupBy重载使您可以指定自定义IEqualityComparer ,以便例如可以实现自己的比较字符串列表的方式。

为了实现这一点,这里还有许多其他线程可以比较两个列表。

之所以得到3个组,是因为List<T>用默认的引用相等实现了相等,而不是考虑了任何两个列表之间所包含元素的“顺序相等”。 如果需要这种语义,则必须自己实现IEqualityComparer<IList<T>> (或类似方法),并使用接受相等比较器的重载将其注入到GroupBy查询中。 这是一个示例实现(对于数组,不是列表,但很容易适应)。

如果您对集合相等感到满意(顺序和重复项无关),那么您会很幸运:您可以直接将HashSet<T>和提供的CreateSetComparer方法用于比较器实现:

  var t1 = new Test { Children = new HashSet<string> { "one", "two" } };
  var t2 = new Test { Children = new HashSet<string> { "one", "two" } };
  var t3 = new Test { Children = new HashSet<string> { "one", "three" } };

  var tests = new List<Test> { t1, t2, t3 };

  // Only two groups: { one, two } and { one, three }
  tests.GroupBy(t => t.Children, HashSet<string>.CreateSetComparer())
       .Dump();

问题在于列表不完全相同。 它比较分组的相等性,并且您有两个新的List<string> ,它们并不完全相等。 但是,您可以通过哈希码连接字符串,这将产生正确的结果:

tests.GroupBy(t => String.Join(string.Empty, t.Children.Select(c => c.GetHashCode().ToString())));

我认为没有内置的方法。

在这里查看乔恩·斯基特的回答:

有机会使用Linq(C#)获得唯一记录吗?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM