LINQ의 ThenBy, ThenByDescending 메서드 필요성
이전 포스팅에서는 LINQ에서 OrderBy() 메서드를 사용하여 오름차순으로 정렬하는 방법과 OrderByDescending() 메서드를 사용하여 내림차순으로 정렬하는 방법에 대해 알아보았습니다.
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
'C# > LINQ' 카테고리의 다른 글
[C#]LINQ 특정 값 포함 여부 - Contains 메서드 (0) | 2022.07.18 |
---|---|
[C#]LINQ 거꾸로 뒤집기 - Reverse 메서드 (0) | 2022.07.17 |
[C#]LINQ 정렬 - OrderBy, OrderByDescending 메서드 (0) | 2022.07.17 |
[C#]LINQ 합치기 - Concat 메서드 (0) | 2022.07.17 |
[C#]LINQ 합집합 구하는 방법 - Union 메서드 (0) | 2022.07.17 |
댓글