C#을 공부하게 되면 한 번쯤은 써봤을 LINQ.
각종 컨테이너들을 다룰 수 있는 강력한 기능을 탑재한 도구라서 그런 것 같다.
사실 LINQ는 쿼리 언어의 확장으로써 코드에서도 쿼리를 던질 수가 있다. 데이터베이스에서 데이터를 쿼리하는 방식처럼 C#의 컨테이너들을 다룰 수 있도록 한 기능이다.
Language INtegrated Query
이름도 사실 쿼리이다!
나는 컨테이너 객체에다만 사용해봤기 때문에 몰랐지만, 어지간한 데이터 소스에다가 사용이 가능하다.
객체 (컬렉션), 데이터베이스, XML 문서, 심지어는 csv까지 사용이 가능하다.
LINQ를 이용한 쿼리 작성법
// 데이터 소스 정의 (컬렉션)
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
// 쿼리 작성 (선언적인 구문)
var evenNumbers = from num in numbers
where num % 2 == 0
select num;
// 쿼리 실행 및 결과 처리
foreach (var num in evenNumbers)
{
Console.WriteLine(num);
}
var
키워드는 결과 값의 자료형을 자동으로 추론한다.
from
절에서는 데이터 소스를 지정한다.
where
절은 선택적으로 사용하며, 조건식을 지정하여 데이터를 필터링한다.
orderby
절은 선택적으로 사용하며, 정렬 방식을 지정한다.
select
절은 선택적으로 사용하며, 조회할 데이터를 지정한다.
주의점
데이터베이스 쿼리와 유사한 방식이기 때문에 필터링, 정렬, 그룹화, 조인 등의 다양한 작업을 수행할 수 있다.
이러한 작업들 모두 쿼리를 던지고 필터링을 하다보니까 데이터가 많이 커지고 필터링해야 되는 조건들이 많아진다면 성능이 급감하기 때문에
LINQ를 사용할 때는 데이터가 한 번 가공이 되어있는 것이 매우 중요하다.
쿼리 역시 간결하면 간결할수록 좋다.
대표 메서드 정리
1. Aggregate()
string[] fruits = { "apple", "mango", "orange", "passionfruit", "grape" };
// Determine whether any string in the array is longer than "banana".
string longestName =
fruits.Aggregate("banana",
(longest, next) =>
next.Length > longest.Length ? next : longest,
// Return the final result as an upper case string.
fruit => fruit.ToUpper());
Console.WriteLine(
"The fruit with the longest name is {0}.",
longestName);
// This code produces the following output:
//
// The fruit with the longest name is PASSIONFRUIT.
데이터를 내가 원하는대로 누적하는 메서드이다.
인자로 넣어주는 함수에 따라 컬렉션을 순회하면서 함수의 결과값을 계속 누적해주는 함수이다.
위 내용은 “banana”
라는 시드부터 시작해서
fruits
를 순회하는데, 둘 중 더 큰 값을 longest
에 저장하는 것을 반복한 후,
그 결과에 ToUpper()
를 적용해서 반환해주는 함수를 거치는 것이다.
2. All(), Any()
All()
은 컬렉션의 모든 요소가 특정 조건에 맞는지 확인하는 메서드이다.
인자로 검사하려는 컬렉션과 조건을 받는데 그 조건은 bool형을 반환하는 함수 형태면 된다.
bool allStartWithB = pets.All(pet => pet.Name.StartsWith("B"));
IEnumerable<string> names = from person in people
where person.Pets.All(pet => pet.Age > 5)
select person.LastName;
Any()
의 경우는 All()
과 같은 방식으로 조건을 만족하는 요소가 단 하나라도 있는지 확인한다.
string[] fruits = { "apple", "mango", "orange", "passionfruit", "grape" };
bool ContainLength5 = fruits.Any((element) => element.Length == 5);
3. Average()
List<int> grades = new List<int> { 78, 92, 100, 37, 81 };
double average = grades.Average();
Console.WriteLine("The average grade is {0}.", average);
// This code produces the following output:
//
// The average grade is 77.6.
컬렉션 전체의 평균을 계산한다.
4. Concat()
using System;
public class Example
{
public static void Main()
{
// Make an array of strings. Note that we have included spaces.
string [] s = { "hello ", "and ", "welcome ", "to ",
"this ", "demo! " };
// Put all the strings together.
Console.WriteLine(string.Concat(s));
// Sort the strings, and put them together.
Array.Sort(s);
Console.WriteLine(string.Concat(s));
}
}
// The example displays the following output:
// hello and welcome to this demo!
// and demo! hello this to welcome
컬렉션을 하나로 이어붙여주는 메서드이다.
두 개말고 세 개 이상 요소들도 붙여줄 수가 있다.
참고로 해당 함수로 다른 언어의 string multiplication을 구현해줄 수 있다.
다음은 휴대폰 뒷 4자리 빼고 전부 *
로 만들어주는 함수이다.
public string solution(string phone_number) {
return String.Concat(Enumerable.Repeat("*", phone_number.Length - 4)) + phone_number.Substring(phone_number.Length - 4);
}
5. Contains()
string[] fruits = { "apple", "mango", "orange", "passionfruit", "grape" };
print(fruits.Contains("apple")); //prints true
컬렉션에 해당 요소가 들어있는지 확인한다.
6. Count()
string[] fruits = { "apple", "mango", "orange", "passionfruit", "grape" };
var count = fruits.Count(e => e.Contains('p'));
print(count); //prints 3
컬렉션의 요소 개수를 확인해준다.
7. Distinct()
string[] fruits = { "apple", "grape", "orange", "apple", "grape" };
foreach (var fruit in fruits.Distinct())
{
print(fruit);
}
//prints following output
//apple
//grape
//orange
중복 요소를 전부 제거해준다.
8. Except()
string[] fruitsA = { "apple", "grape", "orange", "pineapple", "passionfruit" };
string[] fruitsB = { "orange", "pineapple", "passionfruit", "banana" };
foreach (var fruit in fruitsA.Except(fruitsB))
{
print(fruit);
}
//prints following output
//apple
//grape
A.Except(B)
면
B 컬렉션에 있는 요소를 제외한 A 컬렉션의 요소를 반환한다.
9. OrderBy()
IEnumerable<Pet> query = pets.OrderBy(pet => pet.Age);
foreach (Pet pet in query)
{
Console.WriteLine("{0} - {1}", pet.Name, pet.Age);
}
/*
This code produces the following output:
Whiskers - 1
Boots - 4
Barley - 8
*/
정렬 함수이다. 오름차순인데,
내림차순 정렬을 원한다면 OrderByDescending()
을 사용하자.
10. 그 외 것들
Sum()
: 컬렉션 요소의 합
Reverse()
: 컬렉션 요소 순서를 뒤집는다.
Repeat()
: 반복되는 값의 요소를 가진 컬렉션 생성
Min()
, Max()
: 가장 작은 요소 또는 큰 요소를 반환한다.
Join()
: 관계형 데이터베이스에서 테이블 행들을 합치는 메서드인데, 해당 기능은 DB의 파트이니 시간나면 따로 찾아보도록 하자.
Uploaded by N2T
'개발 > Unity 내일배움캠프 TIL' 카테고리의 다른 글
C# Action으로 종속성 없애기..? (0) | 2023.08.29 |
---|---|
C# StringBuilder 정리 (0) | 2023.08.28 |
C# 값 vs 참조 형식 (Value vs Reference) (0) | 2023.08.24 |
C# Sort() 메서드 다루기 (0) | 2023.08.23 |
C# DataTable 간단 사용법 (0) | 2023.08.22 |