Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. LINQ sort and group dates by month and day, ignore year

LINQ sort and group dates by month and day, ignore year

Scheduled Pinned Locked Moved C#
csharplinqalgorithmstutorialworkspace
4 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    Mc_Topaz
    wrote on last edited by
    #1

    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.

    Richard DeemingR 1 Reply Last reply
    0
    • M Mc_Topaz

      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.

      Richard DeemingR Offline
      Richard DeemingR Offline
      Richard Deeming
      wrote on last edited by
      #2

      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

      "These people looked deep within my soul and assigned me a number based on the order in which I joined" - Homer

      M L 2 Replies Last reply
      0
      • Richard DeemingR Richard Deeming

        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

        M Offline
        M Offline
        Mc_Topaz
        wrote on last edited by
        #3

        Thank you! The LINQ example worked just fine!

        1 Reply Last reply
        0
        • Richard DeemingR Richard Deeming

          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

          L Offline
          L Offline
          Luc Pattyn
          wrote on last edited by
          #4

          using DateTime.DayOfYear eliminates some of that code... :)

          Luc Pattyn [My Articles] Nil Volentibus Arduum

          1 Reply Last reply
          0
          Reply
          • Reply as topic
          Log in to reply
          • Oldest to Newest
          • Newest to Oldest
          • Most Votes


          • Login

          • Don't have an account? Register

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • World
          • Users
          • Groups