C# LINQ order by and switch expression

T.Zacks 3,996 Reputation points
2022-06-03T18:25:22.547+00:00

See my code

i am trying to order Quarter. order would look like 1Q 2010 2Q 2010 1H 2010 3Q 2010 4Q 2010 2H 2010 2010 FY

List<string> lstperiods = new List<string>();
 lstperiods.Add("1H 2015");
 lstperiods.Add("1H 2014");
 lstperiods.Add("1Q 2015");
 lstperiods.Add("2Q 2015");
 lstperiods.Add("3Q 2015");
 lstperiods.Add("4Q 2015");
 lstperiods.Add("2015 FY");

 lstperiods.Add("1Q 2014");
 lstperiods.Add("2Q 2014");
 lstperiods.Add("3Q 2014");
 lstperiods.Add("4Q 2014");
 lstperiods.Add("2014 FY");


 lstperiods.Add("2010 FY");
 lstperiods.Add("2011 FY");
 lstperiods.Add("2012 FY");
 lstperiods.Add("2013 FY");
 lstperiods.Add("2H 2015");
 lstperiods.Add("2H 2014");

List<string> allperiods = new List<string>();
 allperiods = lstperiods.OrderBy(x => (x.ToString().Contains("FY")
 ? x.ToString().Substring(0, 4)
 : x.ToString().Substring(3, 4)))
 .ThenBy(y => y switch
 {
 y.Contains("1Q") => 1,
 y.Contains("2Q") => 2,
 y.Contains("1H") => 3,
 y.Contains("3Q") => 4,
 y.Contains("4Q") => 5,
 y.Contains("2H") => 6,
 y.Contains("FY") => 7,
 _ => 8
 }).ToList();

the above code did not compile but when i change the code below way then it worked

List<string> allperiods = new List<string>();
 allperiods = lstperiods.OrderBy(x => (x.ToString().Contains("FY")
 ? x.ToString().Substring(0, 4)
 : x.ToString().Substring(3, 4)))
 .ThenBy(y => y switch
 {
 string a when y.Contains("1Q") => 1,
 string b when y.Contains("2Q") => 2,
 string c when y.Contains("1H") => 3,
 string d when y.Contains("3Q") => 4,
 string e when y.Contains("4Q") => 5,
 string f when y.Contains("2H") => 6,
 string g when y.Contains("FY") => 7,
 _ => 8
 }).ToList();

1) tell me what is the meaning of this line string a when y.Contains("1Q") => 1,?
why do i need to declare multiple variable called a,b,c.....g?

2) also please show me other possible ways to compose the above same code ?

3) i have checked switch expression has multiple variation.

Thanks

Developer technologies | C#
0 comments No comments
{count} votes

Accepted answer
  1. Bruce (SqlWork.com) 77,926 Reputation points Volunteer Moderator
    2022-06-03T19:44:58.093+00:00

    pattern match matches the value to the expression. because you need to transform the value before compare, you need to use the var pattern and the when. as you don't need the variable you can just use a placeholder:

    y switch 
    { 
      _ when y.Contains("1Q") => 1, 
      _ when y.Contains("2Q") => 2, 
      _ when y.Contains("1H") => 3, 
      _ when y.Contains("3Q") => 4, 
      _ when y.Contains("4Q") => 5, 
      _ when y.Contains("2H") => 6, 
      _ when y.Contains("FY") => 7, 
      _ => 8 
      } 
    

1 additional answer

Sort by: Most helpful
  1. Karen Payne MVP 35,586 Reputation points Volunteer Moderator
    2022-06-03T19:45:13.257+00:00

    I think a practical example might help, see the following project and search for when.

    And here is a refactor of your code, note the indexer x.ToString()[..4]

    using System;
    using System.Collections.Generic;
    using System.Linq;
    
    namespace ExamplePatternMatching
    {
        partial class Program
        {
            static void Main(string[] args)
            {
                List<string> allperiods = 
                    Periods().OrderBy(x => x.ToString().Contains("FY")
                        ? x.ToString()[..4]
                        : x.ToString().Substring(3, 4))
                    .ThenBy(y => y switch
                    {
                        { } a when y.Contains("1Q") => 1,
                        { } b when y.Contains("2Q") => 2,
                        { } c when y.Contains("1H") => 3,
                        { } d when y.Contains("3Q") => 4,
                        { } e when y.Contains("4Q") => 5,
                        { } f when y.Contains("2H") => 6,
                        { } g when y.Contains("FY") => 7,
                        _ => 8
                    }).ToList();
    
                Console.ReadLine();
            }
    
            public static List<string> Periods() => new()
            {
                    "1H 2015",
                    "1H 2014",
                    "1Q 2015",
                    "2Q 2015",
                    "3Q 2015",
                    "4Q 2015",
                    "2015 FY",
                    "1Q 2014",
                    "2Q 2014",
                    "3Q 2014",
                    "4Q 2014",
                    "2014 FY",
                    "2010 FY",
                    "2011 FY",
                    "2012 FY",
                    "2013 FY",
                    "2H 2015",
                    "2H 2014"
               };
        }
    }
    
    1 person found this answer helpful.

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.