C#/LINQ

[C#]LINQ 특정 필드 순서대로 정렬

DevStory 2022. 7. 17.

LINQ의 ThenBy, ThenByDescending 메서드 필요성

이전 포스팅에서는 LINQ에서 OrderBy() 메서드를 사용하여 오름차순으로 정렬하는 방법과 OrderByDescending() 메서드를 사용하여 내림차순으로 정렬하는 방법에 대해 알아보았습니다.

 

[C#]LINQ 정렬 - OrderBy, OrderByDescending 메서드

LINQ에서 정렬 이번 포스팅은 LINQ에서 추출된 데이터를 오름차순으로 정렬하는 OrderBy() 메서드와 내림차순으로 정렬하는 OrderByDescending() 메서드 사용 방법을 소개합니다. OrderBy() 메서드와 OrderByDes

developer-talk.tistory.com

OrderBy() 메서드와 OrderByDescending() 메서드는 단일 값 또는 단일 프로퍼티를 기반으로 데이터를 정렬합니다. 따라서 여러 값 또는 여러 프로퍼티를 기반으로 데이터를 정렬할 수 없습니다.

 

예를 들어, 다음과 같은 List 객체에서 이름(Name) 프로퍼티를 오름차순으로 정렬하는 것은 가능하지만, 이름을 오름차순으로 정렬하고 나이를 내림차순으로 정렬하는 것은 불가능합니다.

List<Person> listPerson = new List<Person>() { 
  new Person{ Name = "Tom",  Age=30},
  new Person{ Name = "Tom",  Age=33},
  new Person{ Name = "Nick", Age=23},
  new Person{ Name = "Nick", Age=20},
  new Person{ Name = "Elsa", Age=15},
  new Person{ Name = "Elsa", Age=40},
  new Person{ Name = "Elsa", Age=28},
};

그러나 메서드 체이닝으로 ThenBy() 메서드 또는 ThenByDescending() 메서드를 호출하면 여러 값 또는 여러 프로퍼티를 기반으로 데이터를 정렬할 수 있습니다.


ThenBy, ThenByDescending 메서드

LINQ에서 첫 번째 정렬 기준은 OrderBy() 메서드 또는 OrderByDescending() 메서드에 명시하고 두 번째 정렬 기준부터 ThenBy() 또는 ThenByDescending() 메서드에 명시합니다.

 

정렬하고자 하는 프로퍼티가 세 개이며, 전부 오름차순으로 정렬하는 경우 OrderBy() 메서드를 한 번 사용하고 ThenBy() 메서드를 두 번 사용할 수 있습니다.

 

ThenBy() 메서드는 오름차순으로 정렬하며, ThenByDescending() 메서드는 내림차순으로 정렬합니다.


예제 1. 질의 구문

질의 구문에는 OrderBy() 및 OrderByDescending() 메서드가 존재하지 않습니다. 따라서, ThenBy() 메서드와 ThenByDescending() 메서드도 사용할 수 없습니다.

 

대신 orderby 절에서 콤마로 여러 프로퍼티를 작성할 수 있으며, 작성된 순서대로 정렬합니다.

 

다음 예제는 Name 프로퍼티를 기준으로 오름차순으로 정렬 후 Age 프로퍼티를 기준으로 내림차순으로 정렬합니다.

public class Person
{
  public string Name { get; set; }
  public int Age { get; set; }
  public override string ToString()
  {
    return "Name: " + Name + ", Age: " + Age;
  }
}

class Program
{
  static void Main(string[] args)
  {
    List<Person> listPerson = new List<Person>() { 
      new Person{ Name = "Tom",  Age=30},
      new Person{ Name = "Tom",  Age=33},
      new Person{ Name = "Nick", Age=23},
      new Person{ Name = "Nick", Age=20},
      new Person{ Name = "Elsa", Age=15},
      new Person{ Name = "Elsa", Age=40},
      new Person{ Name = "Elsa", Age=28},
    };

    List<Person> linqQueryResult = (from    pesron in listPerson
                                    orderby pesron.Name, pesron.Age descending
                                    select  pesron).ToList();

    Console.WriteLine("질의 구문");
    foreach (Person person in linqQueryResult)
        Console.WriteLine(person.ToString());
  }
}

[실행 결과]

질의 구문
Name: Elsa, Age: 40
Name: Elsa, Age: 28
Name: Elsa, Age: 15
Name: Nick, Age: 23
Name: Nick, Age: 20
Name: Tom, Age: 33
Name: Tom, Age: 30

예제 2. 메서드 구문

메서드 구문에서는 OrderBy() 메서드 또는 OrderByDescending() 메서드 호출 후 ThenBy() 메서드 또는 ThenByDescending() 메서드를 호출합니다.

 

다음 예제는 메서드 구문에서 Name 프로퍼티를 기준으로 오름차순으로 정렬 후 Age 프로퍼티를 기준으로 내림차순으로 정렬합니다.

public class Person
{
  public string Name { get; set; }
  public int Age { get; set; }
  public override string ToString()
  {
    return "Name: " + Name + ", Age: " + Age;
  }
}

class Program
{
  static void Main(string[] args)
  {
    List<Person> listPerson = new List<Person>() { 
      new Person{ Name = "Tom",  Age=30},
      new Person{ Name = "Tom",  Age=33},
      new Person{ Name = "Nick", Age=23},
      new Person{ Name = "Nick", Age=20},
      new Person{ Name = "Elsa", Age=15},
      new Person{ Name = "Elsa", Age=40},
      new Person{ Name = "Elsa", Age=28},
    };

    List<Person> linqMethodResult = listPerson
        .OrderBy(item => item.Name)
        .ThenByDescending(item => item.Age)
        .ToList();

    Console.WriteLine("메서드 구문");
    foreach (Person person in linqMethodResult)
      Console.WriteLine(person.ToString());
  }
}

[실행 결과]

메서드 구문
Name: Elsa, Age: 40
Name: Elsa, Age: 28
Name: Elsa, Age: 15
Name: Nick, Age: 23
Name: Nick, Age: 20
Name: Tom, Age: 33
Name: Tom, Age: 30

예제 3. 정렬 기준이 세 개 이상

이번에는 정렬 기준이 세 개 이상인 경우입니다. 첫 번째 정렬 기준을 OrderBy() 메서드 또는 OrderByDescending() 메서드에 명시하고 두 번째 정렬 기준을 ThenBy() 메서드 또는 ThenByDescending() 메서드에 명시합니다.

 

마찬가지로 세 번째 정렬 기준도 ThenBy() 메서드 또는 ThenByDescending() 메서드에 명시합니다.

 

다음 예제는 Name 프로퍼티를 오름차순으로 정렬, Age 프로퍼티를 내림차순으로 정렬, Salary 프로퍼티를 오름차순으로 정렬합니다.

public class Person
{
  public string Name { get; set; }
  public int Age { get; set; }
  public int Salary { get; set; }
  public override string ToString()
  {
    return "Name: " + Name + ", Age: " + Age + ", Salary: " + Salary;
  }
}

class Program
{
  static void Main(string[] args)
  {
    List<Person> listPerson = new List<Person>() { 
      new Person{ Name = "Tom",  Age=30, Salary = 50000},
      new Person{ Name = "Tom",  Age=30, Salary = 40000},
      new Person{ Name = "Tom",  Age=33, Salary = 45000},
      new Person{ Name = "Tom",  Age=33, Salary = 30000},
      new Person{ Name = "Nick", Age=23, Salary = 60000},
      new Person{ Name = "Nick", Age=23, Salary = 100000},
      new Person{ Name = "Nick", Age=20, Salary = 55000},
      new Person{ Name = "Nick", Age=20, Salary = 65000},
      new Person{ Name = "Elsa", Age=15, Salary = 5000},
      new Person{ Name = "Elsa", Age=15, Salary = 15000},
      new Person{ Name = "Elsa", Age=40, Salary = 10000},
      new Person{ Name = "Elsa", Age=40, Salary = 20000},
    };

    // 1. 질의 구문(Query Syntax) 
    List<Person> linqQueryResult = (from    pesron in listPerson
                                    orderby pesron.Name, pesron.Age descending, pesron.Salary
                                    select  pesron).ToList();

    // 2. 메서드 구문(Method Syntax)
    List<Person> linqMethodResult = listPerson
        .OrderBy(item => item.Name)
        .ThenByDescending(item => item.Age)
        .ThenBy(item => item.Salary)
        .ToList();

    Console.WriteLine("질의 구문");
    foreach (Person person in linqQueryResult)
      Console.WriteLine(person.ToString());

    Console.WriteLine("\n메서드 구문");
    foreach (Person person in linqMethodResult)
      Console.WriteLine(person.ToString());
  }
}

 [실행 결과]

질의 구문
Name: Elsa, Age: 40, Salary: 10000
Name: Elsa, Age: 40, Salary: 20000
Name: Elsa, Age: 15, Salary: 5000
Name: Elsa, Age: 15, Salary: 15000
Name: Nick, Age: 23, Salary: 60000
Name: Nick, Age: 23, Salary: 100000
Name: Nick, Age: 20, Salary: 55000
Name: Nick, Age: 20, Salary: 65000
Name: Tom, Age: 33, Salary: 30000
Name: Tom, Age: 33, Salary: 45000
Name: Tom, Age: 30, Salary: 40000
Name: Tom, Age: 30, Salary: 50000

메서드 구문
Name: Elsa, Age: 40, Salary: 10000
Name: Elsa, Age: 40, Salary: 20000
Name: Elsa, Age: 15, Salary: 5000
Name: Elsa, Age: 15, Salary: 15000
Name: Nick, Age: 23, Salary: 60000
Name: Nick, Age: 23, Salary: 100000
Name: Nick, Age: 20, Salary: 55000
Name: Nick, Age: 20, Salary: 65000
Name: Tom, Age: 33, Salary: 30000
Name: Tom, Age: 33, Salary: 45000
Name: Tom, Age: 30, Salary: 40000
Name: Tom, Age: 30, Salary: 50000

예제 4. Where절과 함께 사용

다음 예제는 Where절과 함께 사용하여 Age 프로퍼티가 20보다 크고 Salary가 30000보다 큰 요소를 필터링 후 Name 프로퍼티를 오름차순으로 정렬, Age 프로퍼티를 내림차순으로 정렬, Salary 프로퍼티를 오름차순으로 정렬합니다.

public class Person
{
  public string Name { get; set; }
  public int Age { get; set; }
  public int Salary { get; set; }
  public override string ToString()
  {
    return "Name: " + Name + ", Age: " + Age + ", Salary: " + Salary;
  }
}

class Program
{
  static void Main(string[] args)
  {
    List<Person> listPerson = new List<Person>() { 
      new Person{ Name = "Tom",  Age=30, Salary = 50000},
      new Person{ Name = "Tom",  Age=30, Salary = 40000},
      new Person{ Name = "Tom",  Age=33, Salary = 45000},
      new Person{ Name = "Tom",  Age=33, Salary = 30000},
      new Person{ Name = "Nick", Age=23, Salary = 60000},
      new Person{ Name = "Nick", Age=23, Salary = 100000},
      new Person{ Name = "Nick", Age=20, Salary = 55000},
      new Person{ Name = "Nick", Age=20, Salary = 65000},
      new Person{ Name = "Elsa", Age=15, Salary = 5000},
      new Person{ Name = "Elsa", Age=15, Salary = 15000},
      new Person{ Name = "Elsa", Age=40, Salary = 10000},
      new Person{ Name = "Elsa", Age=40, Salary = 20000},
    };

    // 1. 질의 구문(Query Syntax) 
    List<Person> linqQueryResult = (from    pesron in listPerson
                                    where   pesron.Age > 20 && pesron.Salary > 30000
                                    orderby pesron.Name, pesron.Age descending, pesron.Salary
                                    select  pesron).ToList();

    // 2. 메서드 구문(Method Syntax)
    List<Person> linqMethodResult = listPerson
        .Where(item => item.Age > 20 && item.Salary > 30000)
        .OrderBy(item => item.Name)
        .ThenByDescending(item => item.Age)
        .ThenBy(item => item.Salary)
        .ToList();

    Console.WriteLine("질의 구문");
    foreach (Person person in linqQueryResult)
      Console.WriteLine(person.ToString());

    Console.WriteLine("\n메서드 구문");
    foreach (Person person in linqMethodResult)
      Console.WriteLine(person.ToString());
  }
}

[실행 결과]

질의 구문
Name: Nick, Age: 23, Salary: 60000
Name: Nick, Age: 23, Salary: 100000
Name: Tom, Age: 33, Salary: 45000
Name: Tom, Age: 30, Salary: 40000
Name: Tom, Age: 30, Salary: 50000

메서드 구문
Name: Nick, Age: 23, Salary: 60000
Name: Nick, Age: 23, Salary: 100000
Name: Tom, Age: 33, Salary: 45000
Name: Tom, Age: 30, Salary: 40000
Name: Tom, Age: 30, Salary: 50000
반응형

댓글