【问题标题】:Nested groups using linq?使用 linq 的嵌套组?
【发布时间】:2013-10-08 13:01:13
【问题描述】:

假设我有一个具有以下属性的对象。

    public string VendorNumber { get; set; }
    public string PartNumber { get; set; }
    public string PartDivision { get; set; }

我有一个包含大约 300 个对象的列表。我试图先按 VendorNumber 对它们进行分组,然后再按 Division 对它们进行分组。之后我应该能够像这样钻入它们:

  1. 供应商 A
    第 1 部分
    --Part 0001
    --Part 0002
    --Part 0003
    第 2 部分
    --Part 0001
  2. 供应商 B
    第 1 区
    --第0023部分 ...等等...

我可以像这样轻松地进行第一个分组:

var vendorGroups =
    from v in vendors
    group v by v.VendorNumber into vg
    select new { VendorNumber = vg.Key, Parts = vg, Count = vg.Count() };

即使参考了此处和 MSDN 上的其他一些帖子,我似乎也无法让嵌套分组工作。谢谢。


这是我从建议中得到的结果:

我在使用建议方面取得了一些进展,但在循环时我似乎无法访问第二级:

var vendorGroups = forecastHelpers
    .GroupBy(x => new { VendorNumber = x.VendorNumber, Division = x.PartDivision, Level = 1 })
    .GroupBy(x => new { VendorNumber = x.Key.VendorNumber }).OrderBy(x => x.Key.VendorNumber);

    foreach (var vendorGroup in vendorGroups)
{
    System.Diagnostics.Debug.WriteLine("VendorNumber: " + vendorGroup.Key.VendorNumber);
    foreach (var divisionGroup in vendorGroup)
    {
        System.Diagnostics.Debug.WriteLine("     Division: " + divisionGroup.Key.Division);
        foreach (var partNumber in divisionGroup)
        {
            System.Diagnostics.Debug.WriteLine("          PartNumber: " + partNumber.PartNumber);
        }
    }
}

更新 2: 也可以这样写:

var vendorGroupings = from f in forecastHelpers
                        group f by new { VendorNumber = f.VendorNumber, Division = f.PartDivision, Level = 2 } into vendorGroups
                        from divisionGroups in
                            (from division in vendorGroups
                            orderby division.PartDivision
                            group division by new { Division = division.PartDivision }) 
                        orderby vendorGroups.Key.VendorNumber
                        group divisionGroups by new { VendorNumber = vendorGroups.Key.VendorNumber, Level = 1 };


foreach (var vendorGroup in vendorGroupings)
{
    System.Diagnostics.Debug.WriteLine("VendorNumber: " + vendorGroup.Key.VendorNumber);

    foreach (var division in vendorGroup)
    {
        System.Diagnostics.Debug.WriteLine("     Division: " + division.Key.Division);

        foreach (var part in division)
        {
            System.Diagnostics.Debug.WriteLine("          PartNumber: " + part.PartNumber);
        }
    }

【问题讨论】:

标签: c# linq grouping


【解决方案1】:

试试这个:

var vendorGroups = vendors.GroupBy(x => new { x.VendorNumber, x.PartDivision})
                          .GroupBy(x => x.Key.VendorNumber);

要访问第二级,您需要输入x.Key.PartDivision,而不仅仅是x.Key(适用于顶级)。


解决您的编辑问题:

var vendorGroups = forecastHelpers
    .GroupBy(x => new { VendorNumber = x.VendorNumber, Division = x.PartDivision, Level = 1 })
    .GroupBy(x => new { VendorNumber = x.Key.VendorNumber }).OrderBy(x => x.Key.VendorNumber);

foreach (var vendorGroup in vendorGroups)
{
    System.Diagnostics.Debug.WriteLine("VendorNumber: " + vendorGroup.Key.VendorNumber);  

    foreach(var division in vendorGroup)
    {
       System.Diagnostics.Debug.WriteLine("Division: " + division.Key.division); 
       foreach (var part in division)
       {
           System.Diagnostics.Debug.WriteLine("Part: " + part.PartNumber); 
       } 
    }
}

【讨论】:

  • 我似乎无法访问第二级...请参阅我更新的帖子。
  • 没关系,我是个白痴。我已经更新了帖子以显示循环。谢谢。
  • @BBauer42 - 编辑显示嵌套循环。看看有没有帮助。
【解决方案2】:
var grouped = from v in vendors
              group v by new { VN = v.VendorNumber, VD = v.PartDivision} into grp
              orderby grp.Key.VN, grp.Key.VD
              select new {VN_VD=grp.Key, Items=grp};

【讨论】:

    【解决方案3】:
    var vendorGroups =
        from v in vendors
        group v by v.VendorNumber into vg
        select new { VendorNumber = vg.Key, Parts = vg, Count = vg.Count() };
    foreach (var vg in vendorGroups)
    {
        var vendor = vg.VendorNumber;
        foreach (var divGroup in vg.Parts.GroupBy(x => x.PartDivision))
        {
            var division = divGroup.Key;
            foreach (var part in divGroup)
            {
                // do stuff with vendor, division, and part
            }
        }
    }
    

    它可能可以用纯粹的查询语法来完成,但我发现它按原样清晰简单。

    【讨论】:

      【解决方案4】:
      var query = from x in set
                  group x by x.VendorNumber into g
                  select new 
                  {
                      VendorNumber = g.Key
                      GroupedBy = g.ToLookup(x => x.PartDivision)                                 
                  };
      
      foreach(var x in query)
      {
         var venderNumber = x.VendorNumber;
         foreach(var y in x.GroupBy)
         {
             var partDivision = y.Key
             foreach(Vendor item in y)
             {
                 //do stuff with vendor
             }
         }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多