'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 |