C# Linq or Lambda expression Group by Week IEnumerable list with date field

后端 未结 6 1387
梦如初夏
梦如初夏 2021-01-01 04:53

I am trying to do a query to an IEnumerable to group by week, for example:

Project(Name, DateStart,ID)

I have

相关标签:
6条回答
  • 2021-01-01 05:04

    You can use the GetWeekOfMonth extension posted here:

    and then do something like:

            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 讨论(0)
  • 2021-01-01 05:08

    I think to simplify this task you can add WeekNumber property into Project class and fill it when you are creating object of Project after you can easy group by WeekNumber property

    Project(Name, DateStart,ID,WeekNumber)
    
    0 讨论(0)
  • 2021-01-01 05:14

    I think just a simple projection will suffice:

    // 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 讨论(0)
  • 2021-01-01 05:22

    You will need to define a function that can determine which week a date is in:

    int GetWeek(DateTime date) { ... }
    

    Then the LINQ query to group is:

    IEnumerable<IGrouping<int, Project>> groupedProjects = 
             myListOfProjects.GroupBy(p => GetWeek(p.DateStart));
    

    You can iterate over the grouped projects list:

    foreach (var weekGroup in groupedProjects)
    {
        int week = weekGroup.Key;
        foreach (var project in weekGroup)
        {
            Console.WriteLine("Week " + week + " | Project: " + project.ID);
        }
    }
    
    0 讨论(0)
  • 2021-01-01 05:23

    In addition to Tim Schmelter's answer you can get the date of the first day in the week then group by that date.

    To get the date of the first day in the week. you can use this code:

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

    then you can group by the first date of the week like this:

    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);
    } 
    
    0 讨论(0)
  • 2021-01-01 05:24
    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 讨论(0)
提交回复
热议问题