Reputation: 81342
I have a list of a class that looks like this
public class MyClass
{
public ComplexType A {get;set;}
public ComplexTypeB B {get;set;}
}
var myList = new List<MyClass>();
I then have a target Dto which looks like this
public class MyTargetDto
{
public ComplexType A {get;set;}
public List<ComplexTypeB> ListOfB {get;set;}
}
It's very similar only that myTargetDto supports grouping by ComplexType
Given a flat list of MyClass, how can I (using Linq) convert it to a target list of MyTargetDto?
Upvotes: 0
Views: 122
Reputation: 3056
As already posted by others, a solution would be
myList.GroupBy(x => x.A, x => x.B)
.Select(g => new MyTargetDto()
{
A = g.Key,
ListOfB = g.ToList()
});
Just wanted you to see an existing shortcut using a GroupBy
overload
myList.GroupBy(x => x.A, x => x.B, (key, g) => new MyTargetDto()
{
A = key,
ListOfB = g.ToList()
});
Upvotes: 0
Reputation: 37271
myList.GroupBy(item => item.A)
.Select(group => new MyTargetDto
{
A = group.Key,
ListOfB = group.Select(item => item.B).ToList()
});
Upvotes: 0
Reputation: 43906
If your ComplexType
does not have an own implementation of Equals
than at first you would need to implement an 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();
}
}
Then you can use this comparer to group your list using 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();
If ComplexType
already has an own implementation of Equals
that works appropriatly, than you can ommit that comparer:
List<MyTargetDto> result = flatList.GroupBy(e => e.A, e => e.B)
.Select(g => new MyTargetDto {
A = g.Key,
ListOfB = g.ToList()})
.ToList();
The first lambda of GroupBy
selects the element by which the list is grouped. This will then be the Key
property in the resulting IGrouping
.
The second lambda selects the elements that should be contained in that group.
The final Select
creates for each group a MyTargetDto
, setting it's A
property to the ComplexType
and creating the ListOfB
.
Upvotes: 0
Reputation: 16966
You should do something like this.
myList.GroupBy(x=>x.A)
.Select(x=> new MyTargetDto()
{
A= x.Key,
ListOfB = x.Select(s=>s.B).ToList()
});
Upvotes: 1