[英]LINQ - Group by calculated field
说我有这样的课:
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
是这里的扩展方法):
data.Where(d => d.Date >= d.Date.StartOfWeek(DayOfWeek.Monday) && d.Date <= d.Date.StartOfWeek(DayOfWeek.Monday).AddDays(6));
注意:我在实际项目中使用的是Entity Framework,但在执行此操作时,我正在从MyClass
表中获取所有数据,并且我想做以上所有事情以适当地过滤和分组数据。
下面的代码使用星期日作为一周的第一天。 要获得星期,您需要将年份中的天除以7。如果一年中的第一天是星期一,则需要在年份中加1,以便星期几为Sun = 0,Monday = 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();
我尝试使用星期数,因此请先按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>>>
字典的Key
是Code
并且字典的Value
是按Week 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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.