다음을 통해 공유


프로젝션 작업

업데이트: 2007년 11월

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

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

메서드

메서드 이름

설명

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 As New List(Of String)(New String() {"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 As New List(Of String)(New String() {"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 As New List(Of Bouquet)(New Bouquet() { _
        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
    */

}

프로젝션 방법에 대한 추가 정보

참고 항목

개념

표준 쿼리 연산자 개요

참조

select 절(C# 참조)

Select 절(Visual Basic)

System.Linq