投影作業 (Visual Basic)

投影是指將物件轉換成新形式的作業,而這個形式通常僅包含後續即將使用的屬性。 透過使用投影,您可以建構根據每個物件所建立的新型別。 您可以投影屬性並對其執行數學函式。 您也可以投影原始物件,而不進行任何變更。

執行投影的標準查詢運算子方法詳列於下一節。

方法

方法名稱 描述 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

另請參閱