[C#] 강력한 데이터 작업 Linq(링큐)
공부하면서 처음에는 아무것도 모르고 넘겼던.. 링큐..
만들다보면 링큐는 작업을 간단하고 쉽게 도와준다.
최대값이나 정렬을 할때 가끔 사용했었는데,
이제서야 책을보고 조금 공부해 보았다.
링큐
링큐는 Language Intergrated Query의 약어로 , C# 언어에 통합된 데이터 질의 기능을 말한다.
질의라는 것이 좀 어색하긴한데, 데이터에 대해 물어본다는 뜻이다.
링큐의 기본적인 3가지 키워드를 소개한다.
- From : 어떤 데이터 집합에서 데이터를 찾을 것인가?
- Where : 어떤 조건의 데이터를 찾을 것인가?
- Select : 어떤 값을 추출 할 것인가?
이정도로 생각하면 좋을 것 같다.
바로 예시를 들어보자.
별점 3점 이상의 영상만 가져오는 법
나는 여러개의 영화 데이터 중에 별점 3점 이상만 가져오는 코드를 작성하고 싶다.
비디오 클래스를 선언한다.
public class Video
{
public string title;
public int star;
}
반복문을 통해 새로운 리스트에 별점 3점이상의 영화들을 담아주었다.
Video[] videos =
{
new Video{ title = "무빙", star = 1},
new Video{ title = "카지노", star = 2},
new Video{ title = "마스크걸", star = 3},
new Video{ title = "킹더랜드", star = 4},
new Video{ title = "오징어 게임", star = 5},
};
List<Video> goodVideos = new List<Video>();
foreach (Video v in videos)
{
if(v.star >= 3)
{
goodVideos.Add(v);
}
}
foreach (var video in goodVideos)
{
Console.WriteLine($"{video.title} : 별점 {video.star} 점");
}
3개의 영상이 선별되었다.
이 작업을 링큐를 이용한 코드로 바꿔보았다.
Video[] videos =
{
new Video{ title = "무빙", star = 1},
new Video{ title = "카지노", star = 2},
new Video{ title = "마스크걸", star = 3},
new Video{ title = "킹더랜드", star = 4},
new Video{ title = "오징어 게임", star = 5},
};
var goodvideos = from video in videos
where video.star >= 3
select video;
foreach (var video in goodvideos)
{
Console.WriteLine($"{video.title} : 별점 {video.star} 점");
}
이 링큐 코드도 똑같은 결과를 준다.
만약 내림차순으로 정렬을 하고 싶다면?
orderby를 사용해주면 된다.
var goodvideos = from video in videos
where video.star >= 3
orderby video.star descending
select video;
정렬하고 싶은 데이터에 오름차순, 내림차순을 정할 수 있다.
기본적으로는 오름차순 이지만 협업을 위해서는 ascending을 명시해주는것도 좋을 것 같다.
Select 로 가져온 형식
기본적으로 형식은 IEnumerable<T> 형식이다.
만약 정렬을 한다면 해당 형식으로 바뀐다.
어쨌든 IEnumerable을 가지고 있기 때문에 foreach문도 가능하다.
무명 형식
꼭 Select에서 위의 형식만을 가져올 필요는 없다,
때때로 변수를 재구성해서 무명 형식으로 뽑아내는것도 가능하다.
var goodvideos = from video in videos
where video.star >= 3
orderby video.star ascending
select new
{title = video.title, star = video.star, description = "평점 3점 이상 영화"};
foreach (var video in goodvideos)
{
Console.WriteLine($"{video.title} : 별점 {video.star} 점\n 설명:{video.description}\n");
}
`a라는 클래스로 변해있다.
더욱 편하게 링큐를 쓰는 법
귀찮게 from부터 select까지 쓸 필요가 없이 IEnumerable의 확장 함수로 링큐를 편하게 쓸 수 있다.
아까의 코드를 이 방식으로 바꿔 보자.
Video[] videos =
{
new Video{ title = "무빙", star = 1},
new Video{ title = "카지노", star = 2},
new Video{ title = "마스크걸", star = 3},
new Video{ title = "킹더랜드", star = 4},
new Video{ title = "오징어 게임", star = 5},
};
var goodvideos = videos.Where(x => x.star >= 3);
foreach (var video in goodvideos)
{
Console.WriteLine($"{video.title} : 별점 {video.star} 점");
}
videos 변수는 배열이라 IEnumerable을 상속받고 있기 때문에, 확장함수로 Where을 통해 조건을 충족하는 데이터를 바로 뽑아 올 수 있다.
단 한줄의 코드로 변했다.
이 상태에서 정렬을 하고 싶으면 ..
var goodvideos = videos.Where(x => x.star >= 3).OrderByDescending(x=>x.star);
이미 오름차순이기 때문에 내림 차순으로 바꿔주었다.
그리고 정렬을 하고나서 2차로 그 안에서 정렬을 또 하고싶은 경우가 생기면 ThenBy를 쓰면 된다.
예전에 인벤토리를 개발할때 쓴적이 있는데, 등급으로 한번 분류를 하고나서 한글의 가나다 순서대로도 정렬해준다.
var goodvideos = videos.Where(x => x.star >= 3).OrderByDescending(x=>x.star).ThenBy(x=>x.title);
그 외에 많이 쓰이는 것들
Max, Min
간단하게 원하는 데이터의 최대값, 최소값을 가져올 수 있다.
var maxStar = videos.Max(x => x.star);
var minStar = videos.Min(x => x.star);
Sum
원하는 데이터의 총 합을 바로 가져올 수 있다.
var sumStar = videos.Sum(x => x.star);
Average
원하는 데이터의 평균값을 가져올 수 있다.
var averageStar = videos.Average(x => x.star);
링큐는 이런식으로 여러가지 귀찮은 데이터 작업들을 도와준다.
모를땐 이 편함을 잘 모르지만, 한번 사용하면.. 너무나도 편하다.
데이터를 합치는 기능과 그룹을 나누는 기능까지 다양한데, 나중에 한번 포스팅 해볼까 한다.