我有一个类的列表,看起来像这样
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的目标列表?
你应该这样做。
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()
});