【问题标题】:C# LINQ NET 3.5 SP1: Using LINQ to group by two fields and assigning a correlative unique ID (integer number) to all member of the groupC# LINQ NET 3.5 SP1:使用 LINQ 按两个字段分组,并为组的所有成员分配一个相关的唯一 ID(整数)
【发布时间】:2018-03-14 11:51:52
【问题描述】:

我有一个源列表,其中每个项目都是一个具有公共属性的类。

物品类别:

public class Item
{
   public DateTime Date
   {
     get;
     set;
   }
   public string ProviderID
   {
     get;
     set;
   }    
   public List<AnotherClass> listOfitems
   {
     get;       
     set;
   }
   public byte[] Img
   {
     get;
     set;
   }
   // Other properties

   public long GroupID
   {
     get;
     set;
   }
}

来源列表例如:

List<Item> mySourceList;

所以想象一下 mySourceList 在开始时如下所示(此处以表格模式表示):

Date        | ProviderID   |  BillID  | QuantityToPay  | State    | GroupID
01/07/2015    9080AB          6453300      2100           Pending      0
20/01/2014    1080ZX          1200000      1500           Pending      0
01/07/2015    9080AB          6454000      1000           Pending      0
23/11/2016    6080AB          7853300     15000           Pending      0
02/10/2015    9080AB          6454100      2000           Pending      0
01/01/2017    2161DV          9200000       500           Pending      0
20/05/2017    8733ZZ          9800153     60000           Pending      0
01/01/2017    2161DV          9200001     21000           Pending      0
01/01/2017    2161DV          9200002     51700           Pending      0
20/05/2017    8733ZZ          9800154     90000           Pending      0
20/04/2017    8733ZZ          9800102     25000           Pending      0
20/06/2017    8733ZZ          9800200     90000           Pending      0
20/04/2017    8733ZZ          9800103     50000           Pending      0

现在使用 LINQ,我想获取另一个列表 myDestList,它先按 Provider 分组,然后按日期字段分组,还按 Provider 分组,然后按日期排序。 此外,我想为包含超过 1 行的每个组(Date,ProviderID)分配一个相关编号(GroupID)(对于同一组的所有成员,该编号应该相同)。仅包含 1 行的组,此相关数将始终为 0。例如,在处理上面的列表后,我想获得下面的列表 myDestList:

Date        | ProviderID   |  BillID  | QuantityToPay  | State    | GroupID
20/01/2014    1080ZX          1200000      1500           Pending      0
01/01/2017    2161DV          9200000       500           Pending      1
01/01/2017    2161DV          9200001     21000           Pending      1
01/01/2017    2161DV          9200002     51700           Pending      1
23/11/2016    6110FB          7853300     15000           Pending      0
20/04/2017    8733ZZ          9800102     25000           Pending      2
20/04/2017    8733ZZ          9800103     50000           Pending      2
20/05/2017    8733ZZ          9800153     60000           Pending      3
20/05/2017    8733ZZ          9800154     90000           Pending      3
20/06/2017    8733ZZ          9800200     90000           Pending      0
01/07/2015    9080AB          6453300      2100           Pending      4
01/07/2015    9080AB          6454000      1000           Pending      4
02/10/2015    9080AB          6454100      2000           Pending      0

我在下面尝试(没有为每个组分配相关编号,因为我不知道该怎么做):

List<Item> myDestList = mySourceList.GroupBy(x => new { x.ProviderID, x.Date }).Select(grp => grp.ToList<Item>()).ToList<Item>();

如何使用 LINQ 做到这一点?

尝试#1

最后我做了以下:

    var grp = mySourceList .GroupBy(e => new { e.ProviderID, e.Date });

    int groupId = 1;
    foreach (var group in grp)
    {
        int id = group.Count() > 1 ? groupId++ : 0;

        // Loop through each item within group
        foreach (var item in group)
            item.GroupID = id;
    }

【问题讨论】:

    标签: c# linq visual-studio-2008 group-by .net-3.5


    【解决方案1】:

    我假设您不想就地更新您的项目,而只需要生成新项目。我也不太清楚其他属性或“AnotherClass”在哪里出现。所以这里有一些代码,它采用了 Item 的缩减版本(只是 Date、ProviderID 和 GroupID)并为您提供所需的结果。
    请注意,分配的 GroupID 不是连续的。

    缩减类:

    public class Item
    {
        public DateTime Date { get; set; }
        public string ProviderID { get; set; }
        public long GroupID { get ; set ; }
    }
    

    填充“mySourceList”(诚然有点粗糙,准备日期解析):

            List<Item> mySourceList = new List<Item>()
            {
                new Item {Date=DateTime.Parse("01/07/2015"), ProviderID = "9080AB", GroupID = 0 },
                new Item {Date=DateTime.Parse("20/01/2014"), ProviderID = "1080ZX", GroupID = 0 },
                new Item {Date=DateTime.Parse("01/07/2015"), ProviderID = "9080AB", GroupID = 0 },
                new Item {Date=DateTime.Parse("23/11/2016"), ProviderID = "6080AB", GroupID = 0 },
                new Item {Date=DateTime.Parse("02/10/2015"), ProviderID = "9080AB", GroupID = 0 },
                new Item {Date=DateTime.Parse("01/01/2017"), ProviderID = "2161DV", GroupID = 0 },
                new Item {Date=DateTime.Parse("20/05/2017"), ProviderID = "8733ZZ", GroupID = 0 },
                new Item {Date=DateTime.Parse("01/01/2017"), ProviderID = "2161DV", GroupID = 0 },
                new Item {Date=DateTime.Parse("01/01/2017"), ProviderID = "2161DV", GroupID = 0 },
                new Item {Date=DateTime.Parse("20/05/2017"), ProviderID = "8733ZZ", GroupID = 0 },
                new Item {Date=DateTime.Parse("20/04/2017"), ProviderID = "8733ZZ", GroupID = 0 },
                new Item {Date=DateTime.Parse("20/06/2017"), ProviderID = "8733ZZ", GroupID = 0 },
                new Item {Date=DateTime.Parse("20/04/2017"), ProviderID = "8733ZZ", GroupID = 0 },
            };
    

    Linq:

            var myDestList = mySourceList.OrderBy(i => i.Date).ThenBy(i => i.ProviderID)
                .GroupBy(x => new {x.ProviderID, x.Date})
                .Select((grp, idx) => new {GroupId = idx+1, GroupCount = grp.Count(), Items = grp})
                .SelectMany(newgrp => newgrp.Items.DefaultIfEmpty(), (g, i) => new { Date=i.Date, ProviderID = i.ProviderID, GroupID = (g.GroupCount == 1 ? 0 : g.GroupId)})
                .OrderBy(i => i.Date).ThenBy(i=>i.ProviderID)
                .ToList();
    

    结果:

    { Date = 20/01/2014 00:00:00, ProviderID = 1080ZX, GroupID = 0 }
    { Date = 01/07/2015 00:00:00, ProviderID = 9080AB, GroupID = 2 }
    { Date = 01/07/2015 00:00:00, ProviderID = 9080AB, GroupID = 2 }
    { Date = 02/10/2015 00:00:00, ProviderID = 9080AB, GroupID = 0 }
    { Date = 23/11/2016 00:00:00, ProviderID = 6080AB, GroupID = 0 }
    { Date = 01/01/2017 00:00:00, ProviderID = 2161DV, GroupID = 5 }
    { Date = 01/01/2017 00:00:00, ProviderID = 2161DV, GroupID = 5 }
    { Date = 01/01/2017 00:00:00, ProviderID = 2161DV, GroupID = 5 }
    { Date = 20/04/2017 00:00:00, ProviderID = 8733ZZ, GroupID = 6 }
    { Date = 20/04/2017 00:00:00, ProviderID = 8733ZZ, GroupID = 6 }
    { Date = 20/05/2017 00:00:00, ProviderID = 8733ZZ, GroupID = 7 }
    { Date = 20/05/2017 00:00:00, ProviderID = 8733ZZ, GroupID = 7 }
    { Date = 20/06/2017 00:00:00, ProviderID = 8733ZZ, GroupID = 0 }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-02-20
      • 1970-01-01
      • 2019-06-06
      • 2014-06-03
      • 1970-01-01
      • 2012-12-27
      • 2011-01-10
      • 1970-01-01
      相关资源
      最近更新 更多