Group items in a list based on two properties using LINQ
c#, linq
Solution
Use `.GroupBy` with composite key.
Sample code:
List<Column> Columns = new List<Column>
{
new Column { LocId = 1 , SecId = 1, StartElevation = 0, EndElevation = 160 },
new Column { LocId = 1 , SecId = 1, StartElevation = 160, EndElevation = 320 },
new Column { LocId = 1 , SecId = 2, StartElevation = 320, EndElevation = 640 },
new Column { LocId = 2 , SecId = 1, StartElevation = 0, EndElevation = 160 },
new Column { LocId = 2 , SecId = 2, StartElevation = 160, EndElevation = 320 }
};
foreach (var group in Columns.GroupBy(c => new { c.LocId, c.SecId }))
{
Console.WriteLine("group: LocId = {0}, SecId = {1}", group.Key.LocId, group.Key.SecId);
foreach(Column column in group)
Console.WriteLine(" item: StartElevation = {0}, EndElevation = {1}", column.StartElevation, column.EndElevation);
}
You can transform the group any way you want:
foreach (var res in Columns.GroupBy(c => new { c.LocId, c.SecId })
.Select(g => new
{
g.Key.LocId,
g.Key.SecId,
MinStartElevation = g.Min(c => c.StartElevation),
MaxEndElevation = g.Max(c => c.EndElevation)
}))
{
Console.WriteLine("LocId = {0}, SecId = {1}, MinStartElevation = {2}, MaxEndElevation = {3}",
res.LocId, res.SecId, res.MinStartElevation, res.MinStartElevation);
}
Problem
I have a `Column` class as below: ``` public class Column { public int LocId { get; set; } public int SecId { get; set; } public double StartElevation { get; set; } public double EndElevation { get; set; } } ``` And a list of `Column` objects: ``` List<Column> Columns = new List<Column>(); ``` For example: ``` Columns: { Column1: { LocId = 1 , SecId = 1, StartElevation = 0, EndElevation = 160 } Column2: { LocId = 1 , SecId = 1, StartElevation = 160, EndElevation = 320 } Column3: { LocId = 1 , SecId = 2, StartElevation = 320, EndElevation = 640 } Column4: { LocId = 2 , SecId = 1, StartElevation = 0, EndElevation = 160 } Column5: { LocId = 2 , SecId = 2, StartElevation = 160, EndElevation = 320 } } ``` I want to apply the below algorithm to the above list using Linq. Go through the `Columns` list and: (A) Choose a list of items that have the the same `LocId`. (B) Then from that list choose another list of items that have the same `SecId`. This will give me a list hopefully which I will perform other things on it. So applying the above algorithm on the data above will be like this. ``` Columns List --------------------------------------------------------- | Column1 Column2 Column3 Column4 Column5 | --------------------------------------------------------- | | (A) | | -------------------------------------------- | | GroupBasedOnLocId GroupBasedOnLocId | | ----------- ----------- | Column1 | | Column4 | | Column2 | | Column5 | | Column3 | ----------- ----------- | | | (B) (B) | | ------------------------- ------------------------- | | | | | | | | GroupBasedOnSecId GroupBasedOnSecId GroupBasedOnSecId GroupBasedOnSecId | | | | | | | | Column1 Column3 Column4 Column5 Column2 ``` How can I accomplish this using LINQ?