在C#中,在列表中对连续日期进行分组的最佳方法是什么?

时间:2014-12-10 05:00:10

标签: c# collections grouping

我有一个日期列表,我想按连续日项目进行分组

所以如果在列表中我有以下日期:

2013年12月31日
2014年1月1日
2014年1月2日
2014年2月1日
2014年2月2日
2014年2月16日
2014年3月13日

我想找到一种方法对此进行分组,以便我得到:

第1组:
2013年12月31日
2014年1月1日
2014年1月2日

第2组:
2014年2月1日
2014年2月2日

第3组:
2014年2月16日

第4组: 2014年3月13日

如您所见,分组基于连续几天的项目。

C#中最好的方法是采用这个列表并将它们转换成这些组吗?

2 个答案:

答案 0 :(得分:5)

以下代码的逻辑非常简单,对列表进行排序并检查天数delta是否大于1.如果是,请为其创建一个新组:

创建测试日期:

//Dates for testing
 List<DateTime> dates = new List<DateTime>()
 { 
      new DateTime(2013,12,31),
      new DateTime(2014,2,2),
     new DateTime(2014,1,1),
     new DateTime(2014,1,2),
     new DateTime(2014,2,1),               
     new DateTime(2014,2,16),
     new DateTime(2014,3,13),
 };

创建群组:

 dates.Sort();
 //this will hold the resulted groups
 var groups = new List<List<DateTime>>();
 // the group for the first element
 var group1 = new List<DateTime>(){dates[0]};
 groups.Add(group1);

 DateTime lastDate = dates[0];
 for (int i = 1; i < dates.Count; i++)
 {
     DateTime currDate = dates[i];
     TimeSpan timeDiff = currDate - lastDate;
     //should we create a new group?
     bool isNewGroup = timeDiff.Days > 1;
     if (isNewGroup)
     {
         groups.Add(new List<DateTime>());
     }
     groups.Last().Add(currDate);
     lastDate = currDate;
 }

输出:

enter image description here

答案 1 :(得分:3)

如果您正在寻找非常快速和肮脏的东西,这应该可以解决问题。

IEnumerable<DateTime> dates = ...;
var groups = dates
    .Distinct()
    .OrderBy(date => date)
    .Select((date, i) => new { date, key = date.Subtract(TimeSpan.FromDays(i)) })
    .GroupBy(tuple => tuple.key, tuple => tuple.date);