다음을 통해 공유


프로젝션 작업

프로젝션이란 개체를 다른 형태로 변환하는 작업을 가리키며, 대개는 나중에 사용될 속성만으로 구성되는 경우가 많습니다. 프로젝션을 사용하면 각 개체에서 빌드되는 새 형식을 구성할 수 있습니다. 속성을 프로젝션하여 해당 속성에 대한 수학 함수를 수행할 수 있습니다. 또한 원래 개체를 변경하지 않고 프로젝션할 수도 있습니다.

프로젝션을 수행하는 표준 쿼리 연산자 메서드는 다음 단원에 나열되어 있습니다.

메서드

메서드 이름

설명

C# 쿼리 식 구문

Visual Basic 쿼리 식 구문

추가 정보

Select

변환 함수에 따라 값을 프로젝션합니다.

select

Select

Enumerable.Select

Queryable.Select

SelectMany

변환 함수에 기반하는 값 시퀀스를 프로젝션한 다음 하나의 시퀀스로 평면화합니다.

여러 from 절 사용

여러 From 절 사용

Enumerable.SelectMany

Queryable.SelectMany

쿼리 식 구문 예제

Select

다음 예제에서는 C#으로 작성된 select 절 또는 Visual Basic으로 Select 절을 사용하여 문자열 목록에서 각 문자열의 첫 번째 문자를 프로젝션합니다.

        Dim words = New List(Of String) From {"an", "apple", "a", "day"}

        Dim query = From word In words 
                    Select word.Substring(0, 1)

        Dim sb As New System.Text.StringBuilder()
        For Each letter As String In query
            sb.AppendLine(letter)
        Next

        ' Display the output.
        MsgBox(sb.ToString())

        ' This code produces the following output:

        ' a
        ' a
        ' a
        ' d


            List<string> words = new List<string>() { "an", "apple", "a", "day" };

            var query = from word in words
                        select word.Substring(0, 1);

            foreach (string s in query)
                Console.WriteLine(s);

            /* This code produces the following output:

                a
                a
                a
                d
            */

SelectMany

다음 예제에서는 C#으로 작성된 여러 from 절이나 Visual Basic으로 작성된 From 절을 사용하여 문자열 목록에서 각 문자열의 각 단어를 프로젝션합니다.


        Dim phrases = New List(Of String) From {"an apple a day", "the quick brown fox"}

        Dim query = From phrase In phrases 
                    From word In phrase.Split(" "c) 
                    Select word

        Dim sb As New System.Text.StringBuilder()
        For Each str As String In query
            sb.AppendLine(str)
        Next

        ' Display the output.
        MsgBox(sb.ToString())

        ' This code produces the following output:

        ' an
        ' apple
        ' a
        ' day
        ' the
        ' quick
        ' brown
        ' fox


            List<string> phrases = new List<string>() { "an apple a day", "the quick brown fox" };

            var query = from phrase in phrases
                        from word in phrase.Split(' ')
                        select word;

            foreach (string s in query)
                Console.WriteLine(s);

            /* This code produces the following output:

                an
                apple
                a
                day
                the
                quick
                brown
                fox
            */

Select와 SelectMany

Select() 및 **SelectMany()**의 역할은 모두 소스 값에서 결과 값을 생성하는 것입니다. **Select()**는 모든 소스 값에 대해 하나의 결과 값을 생성합니다. 따라서 전체 결과는 소스 컬렉션과 같은 수의 요소가 있는 컬렉션이 됩니다. 반대로 **SelectMany()**는 각 소스 값에서 연결된 하위 컬렉션을 포함하는 하나의 전체 결과를 생성합니다. **SelectMany()**에 인수로 전달되는 변환 함수는 각 소스 값에 대해 열거 가능한 값 시퀀스를 반환해야 합니다. 그러면 **SelectMany()**가 이러한 열거 가능한 시퀀스를 연결하여 하나의 큰 시퀀스를 만듭니다.

다음 두 그림에서는 이 두 메서드 작업의 개념적인 차이점을 보여 줍니다. 각 경우에 선택자(변환) 함수는 각 소스 값에서 꽃의 배열을 선택한다고 가정합니다.

이 그림에서는 **Select()**에서 소스 컬렉션과 동일한 수의 요소가 있는 컬렉션을 반환하는 방법을 설명합니다.

Select()의 동작에 대한 개념적 설명

이 그림에서는 **SelectMany()**가 중간 배열 시퀀스를 각 중간 배열의 모든 값을 포함하는 하나의 최종 결과 값으로 연결하는 방법을 설명합니다.

SelectMany()의 동작을 보여주는 그래픽

코드 예제

다음 예제에서는 **Select()**와 **SelectMany()**의 동작을 비교합니다. 코드에서는 소스 컬렉션의 꽃 이름 목록 각각에서 첫 두 항목을 가져와 "부케"를 만듭니다. 이 예제에서 변환 함수 Select<TSource, TResult>(IEnumerable<TSource>, Func<TSource, TResult>)가 사용하는 "단일 값"은 그 자체가 값 컬렉션입니다. 이 예제에는 각 하위 시퀀스의 각 문자열을 열거하기 위해 추가적인 foreach(Visual Basic의 경우 For Each) 루프가 필요합니다.

Class Bouquet
    Public Flowers As List(Of String)
End Class

Sub SelectVsSelectMany()
    Dim bouquets = New List(Of Bouquet) From { 
        New Bouquet With {.Flowers = New List(Of String)(New String() {"sunflower", "daisy", "daffodil", "larkspur"})}, 
        New Bouquet With {.Flowers = New List(Of String)(New String() {"tulip", "rose", "orchid"})}, 
        New Bouquet With {.Flowers = New List(Of String)(New String() {"gladiolis", "lily", "snapdragon", "aster", "protea"})}, 
        New Bouquet With {.Flowers = New List(Of String)(New String() {"larkspur", "lilac", "iris", "dahlia"})}}

    Dim output As New System.Text.StringBuilder

    ' Select()
    Dim query1 = bouquets.Select(Function(b) b.Flowers)

    output.AppendLine("Using Select():")
    For Each flowerList In query1
        For Each str As String In flowerList
            output.AppendLine(str)
        Next
    Next

    ' SelectMany()
    Dim query2 = bouquets.SelectMany(Function(b) b.Flowers)

    output.AppendLine(vbCrLf & "Using SelectMany():")
    For Each str As String In query2
        output.AppendLine(str)
    Next

    ' Display the output
    MsgBox(output.ToString())

    ' This code produces the following output:
    '
    ' Using Select():
    ' sunflower
    ' daisy
    ' daffodil
    ' larkspur
    ' tulip
    ' rose
    ' orchid
    ' gladiolis
    ' lily
    ' snapdragon
    ' aster
    ' protea
    ' larkspur
    ' lilac
    ' iris
    ' dahlia

    ' Using SelectMany()
    ' sunflower
    ' daisy
    ' daffodil
    ' larkspur
    ' tulip
    ' rose
    ' orchid
    ' gladiolis
    ' lily
    ' snapdragon
    ' aster
    ' protea
    ' larkspur
    ' lilac
    ' iris
    ' dahlia

End Sub
class Bouquet
{
    public List<string> Flowers { get; set; }
}

static void SelectVsSelectMany()
{
    List<Bouquet> bouquets = new List<Bouquet>() {
        new Bouquet { Flowers = new List<string> { "sunflower", "daisy", "daffodil", "larkspur" }},
        new Bouquet{ Flowers = new List<string> { "tulip", "rose", "orchid" }},
        new Bouquet{ Flowers = new List<string> { "gladiolis", "lily", "snapdragon", "aster", "protea" }},
        new Bouquet{ Flowers = new List<string> { "larkspur", "lilac", "iris", "dahlia" }}
    };

    // *********** Select ***********            
    IEnumerable<List<string>> query1 = bouquets.Select(bq => bq.Flowers);

    // ********* SelectMany *********
    IEnumerable<string> query2 = bouquets.SelectMany(bq => bq.Flowers);

    Console.WriteLine("Results by using Select():");
    // Note the extra foreach loop here.
    foreach (IEnumerable<String> collection in query1)
        foreach (string item in collection)
            Console.WriteLine(item);

    Console.WriteLine("\nResults by using SelectMany():");
    foreach (string item in query2)
        Console.WriteLine(item);

    /* This code produces the following output:

       Results by using Select():
        sunflower
        daisy
        daffodil
        larkspur
        tulip
        rose
        orchid
        gladiolis
        lily
        snapdragon
        aster
        protea
        larkspur
        lilac
        iris
        dahlia

       Results by using SelectMany():
        sunflower
        daisy
        daffodil
        larkspur
        tulip
        rose
        orchid
        gladiolis
        lily
        snapdragon
        aster
        protea
        larkspur
        lilac
        iris
        dahlia
    */

}

참고 항목

작업

방법: 조인을 사용하여 데이터와 LINQ 결합(Visual Basic)

방법: 여러 소스로 개체 컬렉션 채우기(LINQ)

방법: LINQ 쿼리 결과를 특정 형식으로 반환(Visual Basic)

방법: 그룹을 사용하여 파일을 여러 파일로 분할(LINQ)

참조

select 절(C# 참조)

Select 절(Visual Basic)

System.Linq

개념

표준 쿼리 연산자 개요