Structure PetOwner
Public Name As String
Public Pets() As String
End Structure
Sub SelectManyEx3()
' Create an array of PetOwner objects.
Dim petOwners() As PetOwner =
{New PetOwner With
{.Name = "Higa", .Pets = New String() {"Scruffy", "Sam"}},
New PetOwner With
{.Name = "Ashkenazi", .Pets = New String() {"Walker", "Sugar"}},
New PetOwner With
{.Name = "Price", .Pets = New String() {"Scratches", "Diesel"}},
New PetOwner With
{.Name = "Hines", .Pets = New String() {"Dusty"}}}
' Project an anonymous type that consists of
' the owner's name and the pet's name (string).
Dim query =
petOwners _
.SelectMany(
Function(petOwner) petOwner.Pets,
Function(petOwner, petName) New With {petOwner, petName}) _
.Where(Function(ownerAndPet) ownerAndPet.petName.StartsWith("S")) _
.Select(Function(ownerAndPet) _
New With {.Owner = ownerAndPet.petOwner.Name,
.Pet = ownerAndPet.petName
Dim output As New System.Text.StringBuilder
For Each obj In query
output.AppendLine(String.Format("Owner={0}, Pet={1}", obj.Owner, obj.Pet))
' Display the output.
Console.WriteLine(output.ToString())
End Sub
' This code produces the following output:
' Owner=Higa, Pet=Scruffy
' Owner=Higa, Pet=Sam
' Owner=Ashkenazi, Pet=Sugar
' Owner=Price, Pet=Scratches
此方法通过使用延迟执行来实现。 即时返回值是一个对象,用于存储执行操作所需的所有信息。 在通过直接调用
GetEnumerator
其方法或在 C#
For Each
或
foreach
Visual Basic 中使用 来枚举对象之前,不会执行此方法表示的查询。
SelectMany<TSource,TCollection,TResult>(IEnumerable<TSource>, Func<TSource,IEnumerable<TCollection>>, Func<TSource,TCollection,TResult>)
当必须将 的
source
元素保留在调用
SelectMany<TSource,TCollection,TResult>(IEnumerable<TSource>, Func<TSource,IEnumerable<TCollection>>, Func<TSource,TCollection,TResult>)
后发生的查询逻辑的范围内时,方法非常有用。 有关代码示例,请参见“示例”部分。 如果 类型的对象与 类型的
TSource
对象之间存在双向关系,即,如果 类型的
TCollection
对象提供属性来检索
TSource
生成它的 对象,则不需要 的此重载
SelectMany<TSource,TCollection,TResult>(IEnumerable<TSource>, Func<TSource,IEnumerable<TCollection>>, Func<TSource,TCollection,TResult>)
TCollection
。 相反,可以使用
SelectMany<TSource,TResult>(IEnumerable<TSource>, Func<TSource,IEnumerable<TResult>>)
并通过 对象
TCollection
导航回
TSource
对象。
在查询表达式语法中,在初始子句转换为 调用
SelectMany
后,每个
from
子句 (C#) 或
From
子句 (Visual Basic) 。
public:
generic <typename TSource, typename TCollection, typename TResult>
[System::Runtime::CompilerServices::Extension]
static System::Collections::Generic::IEnumerable<TResult> ^ SelectMany(System::Collections::Generic::IEnumerable<TSource> ^ source, Func<TSource, int, System::Collections::Generic::IEnumerable<TCollection> ^> ^ collectionSelector, Func<TSource, TCollection, TResult> ^ resultSelector);
public static System.Collections.Generic.IEnumerable<TResult> SelectMany<TSource,TCollection,TResult> (this System.Collections.Generic.IEnumerable<TSource> source, Func<TSource,int,System.Collections.Generic.IEnumerable<TCollection>> collectionSelector, Func<TSource,TCollection,TResult> resultSelector);
static member SelectMany : seq<'Source> * Func<'Source, int, seq<'Collection>> * Func<'Source, 'Collection, 'Result> -> seq<'Result>
<Extension()>
Public Function SelectMany(Of TSource, TCollection, TResult) (source As IEnumerable(Of TSource), collectionSelector As Func(Of TSource, Integer, IEnumerable(Of TCollection)), resultSelector As Func(Of TSource, TCollection, TResult)) As IEnumerable(Of TResult)
TSource
此方法通过使用延迟执行来实现。 即时返回值是一个对象,用于存储执行操作所需的所有信息。 在通过直接调用
GetEnumerator
其方法或在 C#
For Each
或
foreach
Visual Basic 中使用 来枚举对象之前,不会执行此方法表示的查询。
SelectMany<TSource,TCollection,TResult>(IEnumerable<TSource>, Func<TSource,Int32,IEnumerable<TCollection>>, Func<TSource,TCollection,TResult>)
当必须将 的
source
元素保留在调用
SelectMany<TSource,TCollection,TResult>(IEnumerable<TSource>, Func<TSource,Int32,IEnumerable<TCollection>>, Func<TSource,TCollection,TResult>)
后发生的查询逻辑的范围内时,方法非常有用。 有关代码示例,请参见“示例”部分。 如果 类型的对象与 类型的
TSource
对象之间存在双向关系,即,如果 类型的
TCollection
对象提供属性来检索
TSource
生成它的 对象,则不需要 的此重载
SelectMany<TSource,TCollection,TResult>(IEnumerable<TSource>, Func<TSource,Int32,IEnumerable<TCollection>>, Func<TSource,TCollection,TResult>)
TCollection
。 相反,可以使用
SelectMany<TSource,TResult>(IEnumerable<TSource>, Func<TSource,Int32,IEnumerable<TResult>>)
并通过 对象
TCollection
导航回
TSource
对象。
public:
generic <typename TSource, typename TResult>
[System::Runtime::CompilerServices::Extension]
static System::Collections::Generic::IEnumerable<TResult> ^ SelectMany(System::Collections::Generic::IEnumerable<TSource> ^ source, Func<TSource, System::Collections::Generic::IEnumerable<TResult> ^> ^ selector);
public static System.Collections.Generic.IEnumerable<TResult> SelectMany<TSource,TResult> (this System.Collections.Generic.IEnumerable<TSource> source, Func<TSource,System.Collections.Generic.IEnumerable<TResult>> selector);
static member SelectMany : seq<'Source> * Func<'Source, seq<'Result>> -> seq<'Result>
<Extension()>
Public Function SelectMany(Of TSource, TResult) (source As IEnumerable(Of TSource), selector As Func(Of TSource, IEnumerable(Of TResult))) As IEnumerable(Of TResult)
TSource
下面的代码示例演示如何使用
SelectMany<TSource,TResult>(IEnumerable<TSource>, Func<TSource,IEnumerable<TResult>>)
对数组执行一对多投影。
class PetOwner
public string Name { get; set; }
public List<String> Pets { get; set; }
public static void SelectManyEx1()
PetOwner[] petOwners =
{ new PetOwner { Name="Higa, Sidney",
Pets = new List<string>{ "Scruffy", "Sam" } },
new PetOwner { Name="Ashkenazi, Ronen",
Pets = new List<string>{ "Walker", "Sugar" } },
new PetOwner { Name="Price, Vernette",
Pets = new List<string>{ "Scratches", "Diesel" } } };
// Query using SelectMany().
IEnumerable<string> query1 = petOwners.SelectMany(petOwner => petOwner.Pets);
Console.WriteLine("Using SelectMany():");
// Only one foreach loop is required to iterate
// through the results since it is a
// one-dimensional collection.
foreach (string pet in query1)
Console.WriteLine(pet);
// This code shows how to use Select()
// instead of SelectMany().
IEnumerable<List<String>> query2 =
petOwners.Select(petOwner => petOwner.Pets);
Console.WriteLine("\nUsing Select():");
// Notice that two foreach loops are required to
// iterate through the results
// because the query returns a collection of arrays.
foreach (List<String> petList in query2)
foreach (string pet in petList)
Console.WriteLine(pet);
Console.WriteLine();
This code produces the following output:
Using SelectMany():
Scruffy
Walker
Sugar
Scratches
Diesel
Using Select():
Scruffy
Walker
Sugar
Scratches
Diesel
Structure PetOwner
Public Name As String
Public Pets() As String
End Structure
Sub SelectManyEx1()
' Create an array of PetOwner objects.
Dim petOwners() As PetOwner =
{New PetOwner With
{.Name = "Higa, Sidney", .Pets = New String() {"Scruffy", "Sam"}},
New PetOwner With
{.Name = "Ashkenazi, Ronen", .Pets = New String() {"Walker", "Sugar"}},
New PetOwner With
{.Name = "Price, Vernette", .Pets = New String() {"Scratches", "Diesel"}}}
' Call SelectMany() to gather all pets into a "flat" sequence.
Dim query1 As IEnumerable(Of String) =
petOwners.SelectMany(Function(petOwner) petOwner.Pets)
Dim output As New System.Text.StringBuilder("Using SelectMany():" & vbCrLf)
' Only one foreach loop is required to iterate through
' the results because it is a one-dimensional collection.
For Each pet As String In query1
output.AppendLine(pet)
' This code demonstrates how to use Select() instead
' of SelectMany() to get the same result.
Dim query2 As IEnumerable(Of String()) =
petOwners.Select(Function(petOwner) petOwner.Pets)
output.AppendLine(vbCrLf & "Using Select():")
' Notice that two foreach loops are required to iterate through
' the results because the query returns a collection of arrays.
For Each petArray() As String In query2
For Each pet As String In petArray
output.AppendLine(pet)
' Display the output.
Console.WriteLine(output.ToString())
End Sub
' This code produces the following output:
' Using SelectMany():
' Scruffy
' Sam
' Walker
' Sugar
' Scratches
' Diesel
' Using Select():
' Scruffy
' Sam
' Walker
' Sugar
' Scratches
' Diesel
此方法通过使用延迟执行来实现。 即时返回值是一个对象,用于存储执行操作所需的所有信息。 在通过直接调用
GetEnumerator
其方法或在 C#
For Each
或
foreach
Visual Basic 中使用 来枚举对象之前,不会执行此方法表示的查询。
方法
SelectMany<TSource,TResult>(IEnumerable<TSource>, Func<TSource,IEnumerable<TResult>>)
枚举输入序列,使用转换函数将每个元素映射到 ,
IEnumerable<T>
然后枚举并生成每个此类
IEnumerable<T>
对象的元素。 也就是说,对于 的每个元素
source
,
selector
将调用 并返回一系列值。
SelectMany<TSource,TResult>(IEnumerable<TSource>, Func<TSource,IEnumerable<TResult>>)
然后,将此集合的二维集合平展为一维
IEnumerable<T>
并返回它。 例如,如果查询使用
SelectMany<TSource,TResult>(IEnumerable<TSource>, Func<TSource,IEnumerable<TResult>>)
获取数据库中每个客户) 类型的
Order
订单 (,则结果的类型为
IEnumerable<Order>
C# 或
IEnumerable(Of Order)
Visual Basic。 如果查询改为使用
Select
来获取订单,则不会组合订单集合集合,并且结果的类型为
IEnumerable<List<Order>>
C# 或
IEnumerable(Of List(Of Order))
Visual Basic。
在查询表达式语法中,在初始子句转换为 调用
SelectMany
后,每个
from
子句 (C#) 或
From
子句 (Visual Basic) 。
public:
generic <typename TSource, typename TResult>
[System::Runtime::CompilerServices::Extension]
static System::Collections::Generic::IEnumerable<TResult> ^ SelectMany(System::Collections::Generic::IEnumerable<TSource> ^ source, Func<TSource, int, System::Collections::Generic::IEnumerable<TResult> ^> ^ selector);
public static System.Collections.Generic.IEnumerable<TResult> SelectMany<TSource,TResult> (this System.Collections.Generic.IEnumerable<TSource> source, Func<TSource,int,System.Collections.Generic.IEnumerable<TResult>> selector);
static member SelectMany : seq<'Source> * Func<'Source, int, seq<'Result>> -> seq<'Result>
<Extension()>
Public Function SelectMany(Of TSource, TResult) (source As IEnumerable(Of TSource), selector As Func(Of TSource, Integer, IEnumerable(Of TResult))) As IEnumerable(Of TResult)
TSource
下面的代码示例演示如何使用
SelectMany<TSource,TResult>(IEnumerable<TSource>, Func<TSource,Int32,IEnumerable<TResult>>)
对数组执行一对多投影,并使用每个外部元素的索引。
class PetOwner
public string Name { get; set; }
public List<string> Pets { get; set; }
public static void SelectManyEx2()
PetOwner[] petOwners =
{ new PetOwner { Name="Higa, Sidney",
Pets = new List<string>{ "Scruffy", "Sam" } },
new PetOwner { Name="Ashkenazi, Ronen",
Pets = new List<string>{ "Walker", "Sugar" } },
new PetOwner { Name="Price, Vernette",
Pets = new List<string>{ "Scratches", "Diesel" } },
new PetOwner { Name="Hines, Patrick",
Pets = new List<string>{ "Dusty" } } };
// Project the items in the array by appending the index
// of each PetOwner to each pet's name in that petOwner's
// array of pets.
IEnumerable<string> query =
petOwners.SelectMany((petOwner, index) =>
petOwner.Pets.Select(pet => index + pet));
foreach (string pet in query)
Console.WriteLine(pet);
// This code produces the following output:
// 0Scruffy
// 0Sam
// 1Walker
// 1Sugar
// 2Scratches
// 2Diesel
// 3Dusty
Structure PetOwner
Public Name As String
Public Pets() As String
End Structure
Sub SelectManyEx2()
' Create an array of PetOwner objects.
Dim petOwners() As PetOwner =
{New PetOwner With
{.Name = "Higa, Sidney", .Pets = New String() {"Scruffy", "Sam"}},
New PetOwner With
{.Name = "Ashkenazi, Ronen", .Pets = New String() {"Walker", "Sugar"}},
New PetOwner With
{.Name = "Price, Vernette", .Pets = New String() {"Scratches", "Diesel"}},
New PetOwner With
{.Name = "Hines, Patrick", .Pets = New String() {"Dusty"}}}
' Project the items in the array by appending the index
' of each PetOwner to each pet's name in that petOwner's
' array of pets.
Dim query As IEnumerable(Of String) =
petOwners.SelectMany(Function(petOwner, index) _
petOwner.Pets.Select(Function(pet) _
index.ToString() + pet))
Dim output As New System.Text.StringBuilder
For Each pet As String In query
output.AppendLine(pet)
' Display the output.
Console.WriteLine(output.ToString())
End Sub
此方法通过使用延迟执行来实现。 即时返回值是一个对象,用于存储执行操作所需的所有信息。 在通过直接调用
GetEnumerator
其方法或在 C#
For Each
或
foreach
Visual Basic 中使用 来枚举对象之前,不会执行此方法表示的查询。
方法
SelectMany<TSource,TResult>(IEnumerable<TSource>, Func<TSource,Int32,IEnumerable<TResult>>)
枚举输入序列,使用转换函数将每个元素映射到 ,
IEnumerable<T>
然后枚举并生成每个此类
IEnumerable<T>
对象的元素。 也就是说,对于 的每个元素
source
,
selector
将调用 并返回一系列值。
SelectMany<TSource,TResult>(IEnumerable<TSource>, Func<TSource,Int32,IEnumerable<TResult>>)
然后,将此集合的二维集合平展为一维
IEnumerable<T>
并返回它。 例如,如果查询使用
SelectMany<TSource,TResult>(IEnumerable<TSource>, Func<TSource,Int32,IEnumerable<TResult>>)
获取数据库中每个客户) 类型的
Order
订单 (,则结果的类型为
IEnumerable<Order>
C# 或
IEnumerable(Of Order)
Visual Basic。 如果查询改为使用
Select
来获取订单,则不会组合订单集合集合,并且结果的类型为
IEnumerable<List<Order>>
C# 或
IEnumerable(Of List(Of Order))
Visual Basic。
第一个参数表示
selector
要处理的元素。 第二个参数表示
selector
源序列中该元素的从零开始的索引。 例如,如果元素采用已知顺序并且你想要对特定索引处的元素执行某些操作,则这非常有用。 如果要检索一个或多个元素的索引,它也很有用。