投影是指将对象转换为通常只包含其随后使用属性的新形式的操作。 通过使用投影,可以构造从每个对象生成的新类型。 可以投影属性并对该属性执行数学函数。 还可以投影原始对象,而无需更改它。
以下部分列出了执行投影的标准查询运算符方法。
方法
方法名 | 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()
返回与源集合具有相同数量的元素的集合。
此图描述了如何将 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
另请参阅
- System.Linq
- 标准查询运算符概述 (Visual Basic)
- Select 子句
- 如何:使用联接合并数据
- 如何:从多个源填充对象集合(LINQ)(Visual Basic)
- 如何:将 LINQ 查询结果作为特定类型返回
- 如何:通过组将文件分成多个文件(LINQ)(Visual Basic)