프로그래밍 공부/C# 프로그래밍

[C#] 강력한 데이터 작업 Linq(링큐)

데브준우 2023. 9. 24. 01:39

공부하면서 처음에는 아무것도 모르고 넘겼던.. 링큐..

만들다보면 링큐는 작업을 간단하고 쉽게 도와준다.

최대값이나 정렬을 할때 가끔 사용했었는데,

이제서야 책을보고 조금 공부해 보았다.


링큐

 

링큐는 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);

 


링큐는 이런식으로 여러가지 귀찮은 데이터 작업들을 도와준다.

모를땐 이 편함을 잘 모르지만, 한번 사용하면.. 너무나도 편하다.

 

데이터를 합치는 기능과 그룹을 나누는 기능까지 다양한데, 나중에 한번 포스팅 해볼까 한다.