按组日期范围,计数和排序LINQ中的每个组

Bou*_*ory 6 c# linq

我有一个存储在我的对象中的日期集合.这是样本数据.实时,日期将来自服务电话,我将不知道将返回多少日期和数量:

        var ListHeader = new List<ListHeaderData>
        {
            new ListHeaderData
            {
                EntryDate = new DateTime(2013, 8, 26)
            },
            new ListHeaderData
            {
                EntryDate = new DateTime(2013, 9, 11)
            },
            new ListHeaderData
            {
                EntryDate = new DateTime(2013, 1, 1)
            },
            new ListHeaderData
            {
                EntryDate = new DateTime(2013, 9, 15)
            },
            new ListHeaderData
            {
                EntryDate = new DateTime(2013, 9, 17)
            },
            new ListHeaderData
            {
                EntryDate = new DateTime(2013, 9, 5)
            },
        };
Run Code Online (Sandbox Code Playgroud)

我现在需要按日期范围进行分组,如下所示:

   Today (1) <- contains the date 9/17/2013 and count of 1
   within 2 weeks (3) <- contains dates 9/15,9/11,9/5 and count of 3
   More than 2 weeks (2) <- contains dates 8/26, 1/1 and count of 2
Run Code Online (Sandbox Code Playgroud)

这是我的LINQ声明,它没有实现我的需要,但我认为我在球场(如果我不是那么善良):

                   var defaultGroups = from l in ListHeader
                                    group l by l.EntryDate into g
                                    orderby g.Min(x => x.EntryDate)
                                    select new { GroupBy = g };
Run Code Online (Sandbox Code Playgroud)

这按个别日期分组,因此我有6个组,每个组有1个日期.如何按每个组中的日期范围,计数和排序进行分组?提前感谢.

Sri*_*vel 5

这样做怎么样?

引入一个新属性进行分组和分组.

class ListHeaderData
{
    public DateTime EntryDate;
    public int DateDifferenceFromToday
    {
        get
        {
            TimeSpan difference = DateTime.Today - EntryDate.Date;
            if (difference.TotalDays == 0)//today
            {
                return 1;
            }
            else if (difference.TotalDays <= 14)//less than 2 weeks
            {
                return 2;
            }
            else
            {
                return 3;//something else
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑:正如@servy在评论中指出的那样,其他开发人员可能会混淆int使用a enum会更具可读性.

所以,你的类的修改版本看起来像这样

class ListHeaderData
{
    public DateTime EntryDate;
    public DateRange DateDifferenceFromToday
    {
        get
        {
            //I think for this version no comments needed names are self explanatory
            TimeSpan difference = DateTime.Today - EntryDate.Date;
            if (difference.TotalDays == 0)
            {
                return DateRange.Today;
            }
            else if (difference.TotalDays <= 14)
            {
                return DateRange.LessThanTwoWeeks;
            }
            else
            {
                return DateRange.MoreThanTwoWeeks;
            }
        }
    }
}

enum DateRange
{ 
    None = 0,
    Today = 1,
    LessThanTwoWeeks = 2,
    MoreThanTwoWeeks = 3
}
Run Code Online (Sandbox Code Playgroud)

并像这样使用它

 var defaultGroups = from l in ListHeader
     group l by l.DateDifferenceFromToday into g // <--Note group by DateDifferenceFromToday
     orderby g.Min(x => x.EntryDate)
     select new { GroupBy = g };
Run Code Online (Sandbox Code Playgroud)


Ser*_*kiy 5

引入数组,其中包含要分组的范围.这是两个范围 - 今天(零天)和14天(两周):

var today = DateTime.Today;
var ranges = new List<int?> { 0, 14 };
Run Code Online (Sandbox Code Playgroud)

现在按照它所属的范围对您的项目进行分组.如果没有合适的范围(所有日期超过两周),则将使用默认null范围值:

var defaultGroups = 
      from h in ListHeader
      let daysFromToday = (int)(today - h.EntryDate).TotalDays
      group h by ranges.FirstOrDefault(range => daysFromToday <= range) into g
      orderby g.Min(x => x.EntryDate)
      select g;
Run Code Online (Sandbox Code Playgroud)

更新:添加自定义范围以进行分组:

var ranges = new List<int?>();
ranges.Add(0); // today
ranges.Add(7*2); // two weeks
ranges.Add(DateTime.Today.Day); // within current month
ranges.Add(DateTime.Today.DayOfYear); // within current year
ranges.Sort();
Run Code Online (Sandbox Code Playgroud)