LINQ - 按计算字段分组

时间:2017-04-03 10:26:20

标签: c# linq

说我有这样的课程:

public class MyClass 
{
    public DateTime Date { get; set; }
    public string Code { get; set; }
}

有些值如:

| Date          | Code  |
|------------   |------ |
| 03/04/2017    | 1234  |
| 31/03/2017    | 1234  |
| 29/03/2017    | 1234  |
| 29/03/2017    | 4321  |
| 25/03/2017    | 4321  |
| ...           | ...   |

我希望按Code字段对这些进行分组,并按日期分组,但我希望将日期按范围分组。对此的计算将在一周的开始(该周的周一)以及一周的结束(该周的周五)找到日期,然后给我一些结果,如:

| 03/04/2017    | 1234  | < week beginning 03/04 and code=1234

| 31/03/2017    | 1234  | < week beginning 27/03 and code=1234
| 29/03/2017    | 1234  |

| 29/03/2017    | 4321  | < week beginning 27/03 and code=4321

| 25/03/2017    | 4321  | < week beginning 20/03 and code=4321

我尝试过做范围,但我认为我正在做的事情非常无用(StartOfWeek是来自here的扩展方法):

data.Where(d => d.Date >= d.Date.StartOfWeek(DayOfWeek.Monday) && d.Date <= d.Date.StartOfWeek(DayOfWeek.Monday).AddDays(6));

注意:我正在为实际项目使用Entity Framework,但是当我这样做时,我正在从MyClass表中获取所有数据,我想要做以上所有操作来过滤和分组数据适当。

2 个答案:

答案 0 :(得分:0)

以下代码使用星期日作为一周的第一天。要获得本周,您需要将年份日除以7.如果一年的第一天是星期一,则需要在一年中添加1,以便星期几是Sun = 0,星期一= 1 ,....自1月1日起是第1天(非0),因此除法方法正常工作。

            DataTable dt = new DataTable();
            dt.Columns.Add("Date",typeof(DateTime));
            dt.Columns.Add("Code",typeof(int));

            dt.Rows.Add(new object[] { DateTime.Parse("04/03/2017"), 1234});
            dt.Rows.Add(new object[] { DateTime.Parse("03/31/2017"), 1234});
            dt.Rows.Add(new object[] { DateTime.Parse("03/29/2017"), 1234});
            dt.Rows.Add(new object[] { DateTime.Parse("03/29/2017"), 4321});
            dt.Rows.Add(new object[] { DateTime.Parse("03/25/2017"), 4321});

            var groups = dt.AsEnumerable().GroupBy(x => (int)(x.Field<DateTime>("Date").DayOfYear + (int)new DateTime(x.Field<DateTime>("Date").Year, 1, 1).DayOfWeek)/7).ToList();

答案 1 :(得分:0)

我尝试使用周数,因此首先按code分组,然后weekOfYear + Year

List<MyClass> date = new List<MyClass>
{
    new MyClass { Date = new DateTime(2017,03,04), Code = "1234"},
    new MyClass { Date = new DateTime(2017,03,05), Code = "1234"},
    new MyClass { Date = new DateTime(2017,03,06), Code = "1234"},
    new MyClass { Date = new DateTime(2017,04,04), Code = "1234"},
    new MyClass { Date = new DateTime(2017,04,05), Code = "1234"},
    new MyClass { Date = new DateTime(2017,04,06), Code = "1234"},
    new MyClass { Date = new DateTime(2017,03,06), Code = "12345"},
    new MyClass { Date = new DateTime(2017,04,04), Code = "12345"},
    new MyClass { Date = new DateTime(2017,04,05), Code = "12345"},
    new MyClass { Date = new DateTime(2017,04,06), Code = "12345"}
            };

var groupbydata = date.GroupBy(x => x.Code).ToDictionary(x => x.Key, x => x.GroupBy(y => CultureInfo.InvariantCulture.Calendar.GetWeekOfYear(y.Date, CalendarWeekRule.FirstFullWeek, DayOfWeek.Monday).ToString() + y.Date.Year.ToString()));

更新

我已经改变了

x => x.GroupBy(y => CultureInfo.InvariantCulture.Calendar.GetWeekOfYear(y.Date, CalendarWeekRule.FirstFullWeek, DayOfWeek.Monday) + y.Date.Year));

x => x.GroupBy(y => CultureInfo.InvariantCulture.Calendar.GetWeekOfYear(y.Date, CalendarWeekRule.FirstFullWeek, DayOfWeek.Monday).ToString() + y.Date.Year.ToString()));

你会得到的 Dictionary<string, IEnumerable<IGrouping<string, MyClass>>> 词典的KeyCode,词典的ValueWeek number + Year分组数据

还尝试将其打印出来

    private static void Print(Dictionary<string, IEnumerable<IGrouping<string, MyClass>>> groupbydata)
    {
        foreach (var d1 in groupbydata)
        {
            Debug.WriteLine("Code : " + d1.Key);

            foreach (var d2 in d1.Value)
            {
                Debug.WriteLine("Week number + Year: " + d2.Key);
                foreach (var d3 in d2)
                {
                    Debug.WriteLine("Date : " + d3.Date);
                }
            }
        }
    }

结果是

  

代码:1234

     

周数+年份:92017

     

日期:3/4/2017 12:00:00 AM

     

日期:3/5/2017 12:00:00 AM

     

周数+年份:102017

     

日期:3/6/2017 12:00:00 AM

     

周数+年份:142017

     

日期:4/4/2017 12:00:00 AM

     

日期:4/5/2017 12:00:00 AM

     

日期:4/6/2017 12:00:00 AM

     

代码:12345

     

周数+年份:102017

     

日期:3/6/2017 12:00:00 AM

     

周数+年份:142017

     

日期:4/4/2017 12:00:00 AM

     

日期:4/5/2017 12:00:00 AM

     

日期:4/6/2017 12:00:00 AM