Reputation: 620
In c#, after enumerating through a collection of 'TeamFixtureResultPage' types i am using the LINQ operator 'GroupBy' to group the items by month using the dateTime value set on the instance. As expected, when its finished processing this returns an IEnumerable<IGrouping<int, TeamFixtureResultPage>>
I would like to have the option of ordering the sorted months and the sorted team fixture result page types either ascending or descending. To achieve this at the moment i have the following code which despite producing the output i desire, it all feels a bit clunky and feels like i'm going against the DRY principles? There is probably better ways to achieve this too.
IEnumerable<IGrouping<int, TeamFixtureResultPage>> groupedFixResList = null;
if (teamFixResLandingPage.FixturesDisplay == "descending")
{
groupedFixResList = seasonLandingPage
.Children<TeamFixtureResultPage>()
.OrderByDescending(x => x.KickOffTime)
.GroupBy(x => x.KickOffTime.Month)
.OrderBy(group => group.Key)
.Reverse();
//example output (descending)
//MAY
// -Fixture 1 20/05/2020
// -Fixture 2 15/05/2020
// -Fixture 3 10/05/2020
//APRIL
// -Fixture 1 27/04/2020
// -Fixture 2 18/04/2020
// -Fixture 3 13/04/2020
}
else
{
groupedFixResList = seasonLandingPage
.Children<TeamFixtureResultPage>()
.OrderBy(x => x.KickOffTime)
.GroupBy(x => x.KickOffTime.Month)
.OrderBy(group => group.Key);
//example output (ascending)
//APRIL
// -Fixture 3 13/04/2020
// -Fixture 2 18/04/2020
// -Fixture 1 27/04/2020
//MAY
// -Fixture 3 10/05/2020
// -Fixture 2 15/05/2020
// -Fixture 1 20/05/2020
}
I have a couple of questions at this point.
Q1. Is it possible to trim this down as i'm effectively calling the following twice
groupedFixResList = seasonLandingPage
.Children<TeamFixtureResultPage>()
Q2. The TeamFixtureResultPage has a lot more properties than what i actually need to pass to the view so is there anyway i can create a new object all within the same LINQ statement e.g. add the following in a .Select somewhere ?
var fixtureResult = new fixtureResult()
{
Scoreline = x.scoreline,
FixtureDate = x.fixtureDate
}
I could do the following after the LINQ statements
var newGroupedFixResList = new List<FixtureResult>();
foreach (var group in groupedFixResList)
{
foreach (var item in group)
{
var fixRes = new FixtureResult()
{
//map properties
}
newGroupedFixResList.Add(fixRes);
}
}
I have this working and may be overthinking this? Can anyone offer any advice please?
Thank you
Upvotes: 1
Views: 85
Reputation: 186
you can use 1\-1 as multiplier that chooses the ordering direction, like so:
bool reverseOrder = teamFixResLandingPage.FixturesDisplay == "descending";
int orderSign = reverseOrder ? -1 : 1;
groupedFixResList = seasonLandingPage
.Children<TeamFixtureResultPage>()
.OrderBy(x => orderSign * x.KickOffTime.Ticks)
.GroupBy(x => x.KickOffTime.Month)
.OrderBy(group => orderSign * group.Key)
I won't say it's pretty, but that's one way to do that in a single statement without code duplication.
Upvotes: 1