c# Linq使用groupby转换集合

本文关键字:转换 集合 groupby 使用 Linq | 更新日期: 2023-09-27 17:53:56

我有一个类的列表,看起来像这样

public class MyClass
{
   public ComplexType A {get;set;}
   public ComplexTypeB B {get;set;}
}
var myList = new List<MyClass>();

然后我有一个目标Dto它看起来像这样

public class MyTargetDto
{
    public ComplexType A {get;set;}
    public List<ComplexTypeB> ListOfB {get;set;}
}

非常相似,只是myTargetDto支持按ComplexType分组

给定MyClass的平面列表,我如何(使用Linq)将其转换为MyTargetDto的目标列表?

c# Linq使用groupby转换集合

你应该这样做。

myList.GroupBy(x=>x.A)
      .Select(x=> new MyTargetDto()
       {
           A= x.Key,
           ListOfB = x.Select(s=>s.B).ToList()
       });

如果您的ComplexType没有自己的Equals实现,那么首先您需要实现IEqualityComparer<ComplexType>:

public class Comparer : IEqualityComparer<ComplexType>
{
    public bool Equals(ComplexType x, ComplexType y)
    {
        // code to check your complex type for equality
    }
    public int GetHashCode(ComplexType obj)
    {
        return obj.GetHashCode();
    }
}

然后您可以使用此比较器使用GroupBy对列表进行分组:

List<MyClass> flatList = ...
List<MyTargetDto> result = flatList.GroupBy(e => e.A, e => e.B, new Comparer())
                                   .Select(g => new MyTargetDto {
                                         A = g.Key,
                                         ListOfB = g.ToList()});
                                    .ToList();

如果ComplexType已经有自己的Equals的实现可以正常工作,那么您可以提交比较器:

List<MyTargetDto> result = flatList.GroupBy(e => e.A, e => e.B)
                                   .Select(g => new MyTargetDto {
                                         A = g.Key,
                                         ListOfB = g.ToList()})
                                    .ToList();

GroupBy的第一个lambda选择列表分组的元素。这将是结果IGrouping中的Key属性。
第二个lambda选择该组中应该包含的元素。

最终的Select为每个组创建一个MyTargetDto,将其A属性设置为ComplexType并创建ListOfB

myList.GroupBy(item => item.A)
    .Select(group => new MyTargetDto
    {
        A = group.Key,
        ListOfB = group.Select(item => item.B).ToList()
    });

正如其他人已经发布的那样,解决方案是

myList.GroupBy(x => x.A, x => x.B)
      .Select(g => new MyTargetDto()
      {
          A = g.Key,
          ListOfB = g.ToList()
      });

只是想让您看到使用GroupBy重载的现有快捷方式

myList.GroupBy(x => x.A, x => x.B, (key, g) => new MyTargetDto()
{
    A = key,
    ListOfB = g.ToList()
});