'Groups the specified bookings based on their consecutive dates

var listForTestGroup = new List<Booking>
            {
                new Booking{Project="HR", Date= DateTime.Parse("01/02/2020") , Allocation= 10},
                new Booking{Project="CRM", Date= DateTime.Parse("01/02/2020") , Allocation= 15},
                new Booking{Project="HR", Date= DateTime.Parse("02/02/2020") , Allocation= 10},
                new Booking{Project="CRM", Date= DateTime.Parse("02/02/2020") , Allocation= 15},

                new Booking{Project="HR", Date= DateTime.Parse("03/02/2020") , Allocation= 15},
                new Booking{Project="CRM", Date= DateTime.Parse("03/02/2020") , Allocation= 15},
                new Booking{Project="HR", Date= DateTime.Parse("04/02/2020") , Allocation= 15},
                new Booking{Project="CRM", Date= DateTime.Parse("04/02/2020") , Allocation= 15}
                ,

                new Booking{Project="HR", Date= DateTime.Parse("05/02/2020") , Allocation= 15},
                new Booking{Project="CRM", Date= DateTime.Parse("05/02/2020") , Allocation= 15},
                new Booking{Project="ECom", Date= DateTime.Parse("05/02/2020") , Allocation= 15},
                new Booking{Project="ECom", Date= DateTime.Parse("06/02/2020") , Allocation= 10}

                ,

                new Booking{Project="CRM", Date= DateTime.Parse("06/02/2020") , Allocation= 15},
                new Booking{Project="ECom", Date= DateTime.Parse("07/02/2020") , Allocation= 10},
                new Booking{Project="CRM", Date= DateTime.Parse("07/02/2020") , Allocation= 15}

            };

Returns :

          [
            { From:01/02/2020 , To:02/02/2020 , [{ Project:CRM , Allocation:15 },{ Project:HR , Allocation:10 }]  },
            { From:03/02/2020 , To:04/02/2020 , [{ Project:CRM , Allocation:15 },{ Project:HR , Allocation:15 }]  },
            { From:05/02/2020 , To:05/02/2020 , [{ Project:CRM , Allocation:15 },{ Project:HR , Allocation:15 },{ Project:ECom , Allocation:15 }]  },
            { From:06/02/2020 , To:07/02/2020 , [{ Project:CRM , Allocation:15 },{ Project:ECom , Allocation:10 }]  }
          ]


Solution 1:[1]

Your grouping logic is not clear. Are you grouping by groups of 4, or did you mean to group by month?

Grouping by month:

var groupings = bookings
    .OrderBy(x => x.Date)
    .GroupBy(x => x.Date.ToString("yyyy-MM"))
    .Select(g => new 
    {
        From = g.Min(x => x.Date), 
        To = g.Max(x => x.Date), 
        Bookings = g.Select(x => new {x.Project, x.Allocation})
    });

Grouping by 4:

var groupings = bookings
    .OrderBy(x => x.Date)
    .Select((b, i) => new { Index = i, Booking = b })
    .GroupBy(g => g.Index / 4)
    .Select(g => new 
    {
        From = g.Min(x => x.Booking.Date), 
        To = g.Max(x => x.Booking.Date), 
        Bookings = g.Select(x => new {x.Booking.Project, x.Booking.Allocation})
    });

Solution 2:[2]

It's a bit tricky question

here is what the question wants

listForTestGroup.
            GroupBy(x => x.Project).
            Select((g, idx) => new { Group = g, ProjectID = idx + 1 }).
            SelectMany(x => x.Group.Select(r => new { r.Date, r.Project, r.Allocation, x.ProjectID })).
            GroupBy(r => r.Date).
            Select((g, idx) => new { Group = g, Rank = idx + 1, SumProjectID = g.Sum(r => r.ProjectID), SumAllocation = g.Sum(r => r.Allocation) }).
            SelectMany(x => x.Group.Select(r => new { r.Date, r.Project, r.Allocation, Diff = r.Date.AddDays(-x.Rank), x.SumProjectID, x.SumAllocation })).
            GroupBy(r => new { r.Diff, r.SumProjectID, r.SumAllocation }).
            Select(r => new { From = r.Min(d => d.Date), To = r.Max(d => d.Date), Items = r.Select(s => new { s.Project, s.Allocation }).Distinct().ToList() }).
            OrderBy(r => r.From).
            ToList();

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Carlo Bos
Solution 2 Payam Amirani