C#Linq或Lambda表达式按周列出IEnumerable列表,带有日期字段
我试图按IEnumerable
进行查询,按周分组,例如:
Project(Name, DateStart,ID)
我有IEnumerable
,我想做一个报告,按周分组。
例如:
Week 1 Project1 8/4/2013 ID1 Project2 9/4/2013 ID2 Week 2 Project1 16/4/2013 ID3 Project2 18/4/2013 ID5 Week 3 Project1 24/4/2013 ID7 Project2 26/4/2013 ID8
如果有人能帮我一把,我真的很感激! 我试图做一个lambda表达但没有成功。
谢谢!
var weekGroups = projects .Select(p => new { Project = p, Year = p.DateStart.Year, Week = CultureInfo.InvariantCulture.Calendar.GetWeekOfYear (p.DateStart, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday) }) .GroupBy(x => new { x.Year, x.Week }) .Select((g, i) => new { WeekGroup = g, WeekNum = i + 1, Year = g.Key.Year, CalendarWeek = g.Key.Week }); foreach (var projGroup in weekGroups) { Console.WriteLine("Week " + projGroup.WeekNum); foreach(var proj in projGroup.WeekGroup) Console.WriteLine("{0} {1} {2}", proj.Project.Name, proj.Project.DateStart.ToString("d"), proj.Project.ID); }
您需要定义一个函数,该函数可以确定日期所在的周:
int GetWeek(DateTime date) { ... }
然后LINQ查询到组是:
IEnumerable> groupedProjects = myListOfProjects.GroupBy(p => GetWeek(p.DateStart));
您可以遍历分组的项目列表:
foreach (var weekGroup in groupedProjects) { int week = weekGroup.Key; foreach (var project in weekGroup) { Console.WriteLine("Week " + week + " | Project: " + project.ID); } }
我认为为了简化此任务,您可以将WeekNumber属性添加到Project类中,并在创建Project的对象后填充它,之后可以轻松按WeekNumber属性进行分组
Project(Name, DateStart,ID,WeekNumber)
我认为只需一个简单的投影即可:
// we'll just use the existing settings on the box. DateTimeFormatInfo dfi = DateTimeFormatInfo.CurrentInfo; var cal = dfi.Calendar; var Projects = GetProjectsFromSomewhere(); // assuming IEnumerable int week = 1; // this *could* be changed and projected in the Select instead. foreach (var wg in from p in Projects group p by cal.GetWeekOfYear( p.StartDate, dfi.CalendarWeekRule, dfi.FirstDayOfWeek)) { Console.WriteLine("Week {0}", week); foreach (var p in wg) { Console.WriteLine(" {0} {1} {2}", p.Name, p.StartDate, p.ID); } week++; }
您可以使用此处发布的GetWeekOfMonth
扩展程序:
然后做类似的事情:
var groups = projects.GroupBy(p => p.Start.GetWeekOfMonth()); foreach (var group in groups) { Console.WriteLine("Week {0}", group.Key); foreach (var project in group) { Console.WriteLine("\t{0} | {1:dd/MM/yyyy} | {2}", project.Name, project.Start, project.Id); } }
除了Tim Schmelter's
回答,您还可以获得该周第一天的日期,然后按该日期分组。
获取本周第一天的日期。 你可以使用这段代码:
public static class DateTimeExtensions { public static DateTime StartOfWeek(this DateTime dt, DayOfWeek startOfWeek) { int diff = dt.DayOfWeek - startOfWeek; if (diff < 0) { diff += 7; } return dt.AddDays(-1 * diff).Date; } }
然后你可以按照这样的第一个星期分组:
var weekGroups = projects .Select(p => new { Project = p }) .GroupBy(x => x.Project.DateStart.StartOfWeek(DayOfWeek.Monday)) .Select((g, i) => new { WeekGroup = g, WeekNum = i + 1 }); foreach (var projGroup in weekGroups) { Console.WriteLine("Week " + projGroup.WeekNum); foreach(var proj in projGroup.WeekGroup) Console.WriteLine("{0} {1} {2}", proj.Project.Name, proj.Project.DateStart.ToString("d"), proj.Project.ID); }