使用LINQ基于两个属性对列表中的项目进行分组

Vah*_*hid 7 c# linq

我有一个Column课程如下:

public class Column
{
    public int LocId { get; set; }
    public int SecId { get; set; }
    public double StartElevation { get; set; }
    public double EndElevation { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

以及Column对象列表:

List<Column> Columns = new List<Column>();
Run Code Online (Sandbox Code Playgroud)

例如:

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 }
}
Run Code Online (Sandbox Code Playgroud)

我想使用Linq将以下算法应用于上面的列表.

浏览Columns列表并:

  • (A)选择具有相同项目的列表LocId.

  • (B)然后从该列表中选择具有相同项目的另一个项目列表SecId.

这将给我一个列表,希望我将在其上执行其他事情.

因此,将上述算法应用于上述数据将是这样的.

                                       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
Run Code Online (Sandbox Code Playgroud)

如何使用LINQ完成此操作?

Ulu*_*rov 6

.GroupBy与复合键一起使用.

示例代码:

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);
}
Run Code Online (Sandbox Code Playgroud)

您可以以任何方式转换组:

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);
}
Run Code Online (Sandbox Code Playgroud)