Операции проекции (Visual Basic)

Проекцией называют операцию преобразования объекта в новую форму, которая часто состоит только из тех его свойств, которые будут использоваться впоследствии. С помощью проекции можно создать новый тип, построенный из каждого объекта. Вы можете проецировать свойство и выполнять над ним математические функции. Также можно проецировать исходный объект, не изменяя его.

Методы стандартных операторов запросов, которые выполняют проецирование, перечислены в следующем разделе.

Методы

Имя метода Description Синтаксис выражения запроса Visual Basic Дополнительные сведения
Выбрать Проецирует значения, основанные на функции преобразования. Select Enumerable.Select

Queryable.Select
SelectMany Проецирует последовательности значений, основанных на функции преобразования, а затем выравнивает их в одну последовательность. Использование нескольких предложений From Enumerable.SelectMany

Queryable.SelectMany
Почтовый индекс Создает последовательность кортежей с элементами из 2–3 указанных последовательностей. Неприменимо. Enumerable.Zip
Queryable.Zip

Примеры синтаксиса выражений запросов

Выбрать

В приведенном ниже примере предложение 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

SelectMany

В приведенном ниже примере несколько предложений 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

Select или SelectMany

Задача обоих методов Select() и SelectMany() заключается в создании результирующего значения (или значений) из исходных значений. Select() создает один результат для каждого исходного значения. Таким образом, общий результат является коллекцией, имеющей то же количество элементов, что и исходная коллекция. SelectMany(), напротив, создает общий результат, содержащий соединенные подколлекции из каждого исходного значения. Функция преобразования, которая передается в качестве аргумента методу SelectMany(), должна возвращать перечисляемую последовательность значений для каждого исходного значения. Эти перечисляемые последовательности затем объединяются SelectMany() для создания одной большой последовательности.

На двух рисунках, приведенных ниже, показаны принципиальные различия между работой этих двух методов. В обоих случаях предполагается, что функция выбора (преобразования) выбирает массив цветов из каждого исходного значения.

На этом рисунке представлено, как Select() возвращает коллекцию, которая имеет то же количество элементов, что и исходная коллекция.

Graphic that shows the action of Select()

На этом рисунке показано, как SelectMany() объединяет промежуточные последовательности массивов в один конечный результат, содержащий все значения из промежуточных массивов.

Graphic showing the action of SelectMany().

Пример кода

В приведенном ниже примере сравнивается действие Select() и SelectMany(). Код создает "букет" цветов, принимая элементы из каждого списка имен цветов в исходной коллекции. В этом примере отдельное значение, используемое функцией преобразования Select<TSource,TResult>(IEnumerable<TSource>, Func<TSource,TResult>), представляет собой коллекцию значений. Этот требует дополнительного цикла 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

См. также