投影操作(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

另请参阅