投影操作(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() 返回与源集合具有相同数量的元素的集合。

展示 Select() 操作的图形

此图描述了如何将 SelectMany() 数组的中间序列串联成一个最终结果值,其中包含每个中间数组中的每个值。

显示 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

另请参阅