프로그래밍/C#

[C#] LINQ 개념 (Language INtegrated Query)

갓똥 2020. 5. 6. 20:20
728x90
반응형

1. 사전 복습

using System;
using System.Collections.Generic;

class Program {
    static void Main() {
        int[] arr = {1, 2, 3, 4, 5};
        
        foreach(int n in arr)
            Console.WriteLine(n)
        
        IEnumerable<int> col = arr;
        
        foreach(int n in col)
            Console.WriteLine(n);
    }
}

 

배열을 하나 만들고 foreach를 이용해 요소를 출력해보는 코드이다.
그런데 foreach의 원리는 결국 배열이 갖고있는 GetEnumerator() 메소드를 호출해 열거자를 꺼내는 방식이였다.
모든 컬렉션은 IEnumerable<T> 인터페이스를 구현해야 하고 배열도 컬렉션이므로 GetEnumerator()메소드가 있다.
그렇다면 IEnumerable<T> 인터페이스로 모든 컬렉션은 가리킬 수 있게 된다.
따라서 foreach에 IEnumerable<T> 참조 변수를 전달할 수 있다.

 ① 모든 컬렉션은 IEnumerable<T> 인터페이스를 구현한다.

    => 열거자(반복자)를 꺼내는 GetEnumerator()메소드가 있다.

    => 모든 컬렉션은 IEnumerable<T> 인터페이스로 참조할 수(가리킬 수) 있다.

 

 ② foreach 원리

    => 열거자(반복자)를 꺼내서 각 요소에 접근 하는 것.

    => foreach 사용 시 IEnumerable<T> 타입의 참조 변수를 전달할 수 있다.

 


2. 핵심 정리

using System;
using System.Collections.Generic;

class Progarm {
    static void Main() {
        // 일반적인 방법
        int[] arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
        
        foreach(int n in arr) {
            if(n % 3 == 0)
                Console.WriteLine(n);
        }
    }
}

 

10개짜리 배열이 있고 3의 배수만 출력해보고 싶다고 해보자.
반복문과 조건을 사용한 아주 일반적인 코드인데 LINQ를 사용해 구현할 수도 있다.

 ① Collection에 있는 요소 중 3의 배수만 얻고 싶다.

    => 반복문과 조건문을 사용해서 직접 구현

    => LINQ 사용

using System;
using System.Collections.Generic;
using System.Linq;

class Progarm {
    static void Main() {
        // LINQ 사용
        int[] arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
        
        IEnumerable<int> e = arr.Where(n => n % 3 == 0);
        // var e = arr.Where(n => n % 3 == 0);
        
        foreach(int n in e)
            Console.WriteLine(n);
    }
}

 

모든 컬렉션은 IEnumerable 인터페이스를 구현했으므로 IEnumerable을 받을 때
람다식으로 조건을 건다.
해당 IEnumerable은 어떠한 컬렉션일텐데 조건에 따라 이미 3의 배수만 들어있게 된다.
따라서 그냥 전부 출력해보면 된다.
Linq를 사용하기 위해서는 네임스페이스를 열어야 한다.

 ② LINQ (Language INtegrated Query)

    => Collection 에 대한 다양한 연산을 위한 Query

    => Collection 에 대한 다양한 연산을 편리하게 만들 수 있다.

    => using System.Linq;

 

 ③ Query에 대한 반환 값 타입

    => IEnumerable<T>

    => var를 사용하는 경우도 많이 있음

 


3. 다른 예제

using System;
using System.Linq;
using System.Collections.Generic;

class Program {
    public static bool IsOdd(int n) {
        return n % 2 == 1;
    }

    static void Main() {
        int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        
        // 배열에서 홀수만 얻고 싶다.
        // IEnumerable<int> e = arr.Where(IsOdd); // 메소드 이용
        IEnumerable<int> e = arr.Where(n => n % 2 == 1); // 람다 표현식 이용
        
        foreach(int n in e)
            Console.WriteLine(n);
    }
}

 ① IEnumerable<int> e = arr.query_method( 조건자 )

 

using System;
using System.Linq;
using System.Collections.Generic;

class Program {

    static void Main() {
        int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        
        // 배열에서 홀수만 얻고 싶다.
        IEnumerable<int> e = arr.Where(n => n % 2 == 1).Select(n => n * 10).Skip(3);
        
        foreach(int n in e)
            Console.WriteLine(n);
    }
}

 

첫 번째 코드는 위에 했던 내용의 복습이다.
IEnumerable 대신 var로 받는 경우도 많다.
두 번째 코드는 query method를 여러개 받을 수 있다는 것을 보여주는 코드이다.
Where 조건으로 홀수만 뽑고
Select를 사용하면 뽑힌 요소들에 대해서만 작업을 할 수 있다. (위에 경우 *10)
Skip을 사용하면 앞의 3개 요소는 건너뛴다. (요소에 포함시키지 않는다)
코딩 관례상 쿼리를 여러개 사용할 경우 " . " 을 기준으로 라인을 맞춰준다.

 

using System;
using System.Linq;
using System.Collections.Generic;

class Program {

    static void Main() {
        int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        
        // 배열에서 홀수만 얻고 싶다.
        IEnumerable<int> e = arr.Where(n => n % 2 == 1)
                                .Select(n => n * 10)
                                .Skip(3);
        
        foreach(int n in e)
            Console.WriteLine(n);
    }
}

이 외에도 수십가지의 쿼리 메소드가 있는데
" . "을 찍어보면 설명과 함께 나오기도 하고, 구글링을 하면 많이 나와서...
나중에 다시 정리해보도록 한다.
728x90
반응형