2013-04-10 109 views
4

我想通過每週做一個查詢到IEnumerable<Object>到組,例如:C#的LINQ或Lambda表達式組

Project(Name, DateStart,ID) 

我有IEnumerable<Project>,我希望做一個報告,按周分組。

對於〔實施例:

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表達式,但沒有成功。

謝謝!

+0

什麼樣IEnumerable'的'?什麼linq提供者(例如Linq-To-SQL,Linq-To-Objects)? – 2013-04-10 13:43:46

+0

Linq-to-Objects。我從我的模型中創建了一個IEnumerable類型的實體。 – user2112420 2013-04-10 13:47:05

+0

請考慮接受幫助你的答案。 – 2016-07-08 06:37:28

回答

0

我認爲要簡化這一任務,你可以添加WeekNumber屬性到項目 級和後補它,當你創建項目的對象,你可以通過WeekNumber財產容易組

Project(Name, DateStart,ID,WeekNumber) 
+0

我不希望從一年的一週訂單,只是組所有屬於一個星期......如果你知道我的意思...... – user2112420 2013-04-10 13:55:53

1

您需要定義一個可確定日期是其中周功能:

int GetWeek(DateTime date) { ... } 

然後LINQ查詢到基團是:

IEnumerable<IGrouping<int, Project>> 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); 
    } 
} 
+0

我可以在那裏調用一個函數嗎? – user2112420 2013-04-10 13:51:29

+0

哪裏?你的意思是在'IGrouping '? – AlexFoxGill 2013-04-10 13:52:29

+1

您可以通過「Calendar.GetWeekOfYear」進行分組,並在第二步中或在對它們進行迭代時「重命名」這些組。 – sloth 2013-04-10 13:53:21

13
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); 
} 
+0

這是天才,這個邏輯對我來說也很好。我有一個人在它上面工作了好幾個小時.. – 2013-06-10 02:36:34

+0

+1,甚至提到這個提問者(http://stackoverflow.com/questions/20689149/split-last-2-weeks-of-data-into-current和前一週/ 20689877#20689877)查看此解決方案。看起來不錯 – 2013-12-19 19:25:04

+0

謝謝。 +1這是一個非常容易理解,並且與Linq進行相當複雜分組的工作示例。將回來再次查看它,直到它燒到我的大腦。 – ppumkin 2015-03-27 16:08:53

0

可以使用GetWeekOfMonth擴展發佈here

,然後做一些事情,如:

 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); 
      } 
     } 
+0

讓我試試這個,讓你知道謝謝! – user2112420 2013-04-10 14:07:49

0

我認爲只需一個簡單的投影就足夠了:

// we'll just use the existing settings on the box. 
DateTimeFormatInfo dfi = DateTimeFormatInfo.CurrentInfo; 
var cal = dfi.Calendar; 

var Projects = GetProjectsFromSomewhere(); // assuming IEnumerable<Project> 

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++; 
} 
0

除了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); 
}