LINQ sort and group dates by month and day, ignore year
-
I have this setup of a list containing dates and strings:
var d0 = new DateTime(2019, 10, 20);
var d1 = new DateTime(2018, 10, 20);
var d2 = new DateTime(2019, 10, 21);
var d3 = new DateTime(2019, 10, 20);
var d4 = new DateTime(2017, 10, 21);
var d5 = new DateTime(2013, 10, 22);
var d6 = new DateTime(2015, 10, 21);
var d7 = new DateTime(2010, 10, 23);
var d8 = new DateTime(1995, 10, 20);
var d9 = new DateTime(2019, 10, 22);var list = new List<(DateTime Date, string Name)>();
list.Add((d0, "D0"));
list.Add((d1, "D1"));
list.Add((d2, "D2"));
list.Add((d3, "D3"));
list.Add((d4, "D4"));
list.Add((d5, "D5"));
list.Add((d6, "D6"));
list.Add((d7, "D7"));
list.Add((d8, "D8"));
list.Add((d9, "D9"));I want to use LINQ to transform the list in the following order:
(2019-10-20, "D0")
(2018-10-20, "D1")
(2019-10-20, "D3")
(1995-10-20, "D8")
(2019-10-21, "D2")
(2017-10-21, "D4")
(2015-10-21, "D6")
(2013-10-22, "D5")
(2019-10-22, "D9")
(2010-10-23, "D7")Notice the month and day decides the order, not the year. I have tried to mess around with LINQ's
GroupBy()
method, but cannot understand how to group dates where months and days are equal. Also there is a sorting rule: Notice the "D0"-item comes before the "D1"-item, even if the "D1"-item has year set to 2018 and the "D0"-item has year set to 2019. -
I have this setup of a list containing dates and strings:
var d0 = new DateTime(2019, 10, 20);
var d1 = new DateTime(2018, 10, 20);
var d2 = new DateTime(2019, 10, 21);
var d3 = new DateTime(2019, 10, 20);
var d4 = new DateTime(2017, 10, 21);
var d5 = new DateTime(2013, 10, 22);
var d6 = new DateTime(2015, 10, 21);
var d7 = new DateTime(2010, 10, 23);
var d8 = new DateTime(1995, 10, 20);
var d9 = new DateTime(2019, 10, 22);var list = new List<(DateTime Date, string Name)>();
list.Add((d0, "D0"));
list.Add((d1, "D1"));
list.Add((d2, "D2"));
list.Add((d3, "D3"));
list.Add((d4, "D4"));
list.Add((d5, "D5"));
list.Add((d6, "D6"));
list.Add((d7, "D7"));
list.Add((d8, "D8"));
list.Add((d9, "D9"));I want to use LINQ to transform the list in the following order:
(2019-10-20, "D0")
(2018-10-20, "D1")
(2019-10-20, "D3")
(1995-10-20, "D8")
(2019-10-21, "D2")
(2017-10-21, "D4")
(2015-10-21, "D6")
(2013-10-22, "D5")
(2019-10-22, "D9")
(2010-10-23, "D7")Notice the month and day decides the order, not the year. I have tried to mess around with LINQ's
GroupBy()
method, but cannot understand how to group dates where months and days are equal. Also there is a sorting rule: Notice the "D0"-item comes before the "D1"-item, even if the "D1"-item has year set to 2018 and the "D0"-item has year set to 2019.You're not grouping the list; you're sorting it. With LINQ:
var sortedSequence = list
.OrderBy(p => p.Date.Month)
.ThenBy(p => p.Date.Day)
.ThenBy(p => p.Name);With a custom comparer:
public class MonthDayNameComparer : IComparer<(DateTime date, string name)>
{
public int Compare((DateTime date, string name) left, (DateTime date, string name) right)
{
int result = left.date.Month.CompareTo(right.date.Month);
if (result == 0) result = left.date.Day.CompareTo(right.date.Day);
if (result == 0) result = StringComparer.Ordinal.Compare(left.name, right.name);
return result;
}
}...
list.Sort(new MonthDayNameComparer());
"These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer
-
You're not grouping the list; you're sorting it. With LINQ:
var sortedSequence = list
.OrderBy(p => p.Date.Month)
.ThenBy(p => p.Date.Day)
.ThenBy(p => p.Name);With a custom comparer:
public class MonthDayNameComparer : IComparer<(DateTime date, string name)>
{
public int Compare((DateTime date, string name) left, (DateTime date, string name) right)
{
int result = left.date.Month.CompareTo(right.date.Month);
if (result == 0) result = left.date.Day.CompareTo(right.date.Day);
if (result == 0) result = StringComparer.Ordinal.Compare(left.name, right.name);
return result;
}
}...
list.Sort(new MonthDayNameComparer());
"These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer
-
You're not grouping the list; you're sorting it. With LINQ:
var sortedSequence = list
.OrderBy(p => p.Date.Month)
.ThenBy(p => p.Date.Day)
.ThenBy(p => p.Name);With a custom comparer:
public class MonthDayNameComparer : IComparer<(DateTime date, string name)>
{
public int Compare((DateTime date, string name) left, (DateTime date, string name) right)
{
int result = left.date.Month.CompareTo(right.date.Month);
if (result == 0) result = left.date.Day.CompareTo(right.date.Day);
if (result == 0) result = StringComparer.Ordinal.Compare(left.name, right.name);
return result;
}
}...
list.Sort(new MonthDayNameComparer());
"These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer
using
DateTime.DayOfYear
eliminates some of that code... :)Luc Pattyn [My Articles] Nil Volentibus Arduum