Enumerable.SelectMany 方法

定义

将序列的每个元素投影到 IEnumerable<T> 并将结果序列合并为一个序列。

重载

SelectMany<TSource,TCollection,TResult>(IEnumerable<TSource>, Func<TSource,Int32,IEnumerable<TCollection>>, Func<TSource,TCollection,TResult>)

将序列的每个元素投影到 IEnumerable<T>,并将结果序列合并为一个序列,并对其中每个元素调用结果选择器函数。 每个源元素的索引用于该元素的中间投影表。

SelectMany<TSource,TCollection,TResult>(IEnumerable<TSource>, Func<TSource,IEnumerable<TCollection>>, Func<TSource,TCollection,TResult>)

将序列的每个元素投影到 IEnumerable<T>,并将结果序列合并为一个序列,并对其中每个元素调用结果选择器函数。

SelectMany<TSource,TResult>(IEnumerable<TSource>, Func<TSource,IEnumerable<TResult>>)

将序列的每个元素投影到 IEnumerable<T> 并将结果序列合并为一个序列。

SelectMany<TSource,TResult>(IEnumerable<TSource>, Func<TSource,Int32,IEnumerable<TResult>>)

将序列的每个元素投影到 IEnumerable<T> 并将结果序列合并为一个序列。 每个源元素的索引用于该元素的投影表。

SelectMany<TSource,TCollection,TResult>(IEnumerable<TSource>, Func<TSource,Int32,IEnumerable<TCollection>>, Func<TSource,TCollection,TResult>)

将序列的每个元素投影到 IEnumerable<T>,并将结果序列合并为一个序列,并对其中每个元素调用结果选择器函数。 每个源元素的索引用于该元素的中间投影表。

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

source 的元素类型。

TCollection

collectionSelector 收集的中间元素的类型。

TResult

结果序列的元素的类型。

参数

source
IEnumerable<TSource>

一个要投影的值序列。

collectionSelector
Func<TSource,Int32,IEnumerable<TCollection>>

一个应用于每个源元素的转换函数;函数的第二个参数表示源元素的索引。

resultSelector
Func<TSource,TCollection,TResult>

应用于中间序列的每个元素的转换函数。

返回

IEnumerable<TResult>

一个 IEnumerable<T>,其元素是通过以下方法得到的:对 source 的每个元素调用一对多转换函数 collectionSelector,然后将这些序列元素中的每一个元素及其相应的源元素映射到一个结果元素。

例外

sourcecollectionSelectorresultSelectornull

注解

此方法通过使用延迟执行来实现。 即时返回值是一个对象,用于存储执行操作所需的所有信息。 除非对象通过直接调用其方法或在 foreach Visual C# 或 For Each Visual Basic 中使用来枚举对象GetEnumerator,否则不会执行此方法表示的查询。

当必须保留调用后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>>) 并导航回 TSource 对象 TCollection

适用于

SelectMany<TSource,TCollection,TResult>(IEnumerable<TSource>, Func<TSource,IEnumerable<TCollection>>, Func<TSource,TCollection,TResult>)

将序列的每个元素投影到 IEnumerable<T>,并将结果序列合并为一个序列,并对其中每个元素调用结果选择器函数。

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, 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,System.Collections.Generic.IEnumerable<TCollection>> collectionSelector, Func<TSource,TCollection,TResult> resultSelector);
static member SelectMany : seq<'Source> * Func<'Source, 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, IEnumerable(Of TCollection)), resultSelector As Func(Of TSource, TCollection, TResult)) As IEnumerable(Of TResult)

类型参数

TSource

source 的元素类型。

TCollection

collectionSelector 收集的中间元素的类型。

TResult

结果序列的元素的类型。

参数

source
IEnumerable<TSource>

一个要投影的值序列。

collectionSelector
Func<TSource,IEnumerable<TCollection>>

应用于输入序列的每个元素的转换函数。

resultSelector
Func<TSource,TCollection,TResult>

应用于中间序列的每个元素的转换函数。

返回

IEnumerable<TResult>

一个 IEnumerable<T>,其元素是通过以下方法得到的:对 source 的每个元素调用一对多转换函数 collectionSelector,然后将这些序列元素中的每一个元素及其相应的源元素映射到一个结果元素。

例外

sourcecollectionSelectorresultSelectornull

示例

下面的代码示例演示如何用于 SelectMany<TSource,TCollection,TResult>(IEnumerable<TSource>, Func<TSource,IEnumerable<TCollection>>, Func<TSource,TCollection,TResult>) 对数组执行一对多投影,并使用结果选择器函数将每个相应元素从源序列中保留到最终调用 Select的范围。

class PetOwner
{
    public string Name { get; set; }
    public List<string> Pets { get; set; }
}

public static void SelectManyEx3()
{
    PetOwner[] petOwners =
        { new PetOwner { Name="Higa",
              Pets = new List<string>{ "Scruffy", "Sam" } },
          new PetOwner { Name="Ashkenazi",
              Pets = new List<string>{ "Walker", "Sugar" } },
          new PetOwner { Name="Price",
              Pets = new List<string>{ "Scratches", "Diesel" } },
          new PetOwner { Name="Hines",
              Pets = new List<string>{ "Dusty" } } };

    // Project the pet owner's name and the pet's name.
    var query =
        petOwners
        .SelectMany(petOwner => petOwner.Pets, (petOwner, petName) => new { petOwner, petName })
        .Where(ownerAndPet => ownerAndPet.petName.StartsWith("S"))
        .Select(ownerAndPet =>
                new
                {
                    Owner = ownerAndPet.petOwner.Name,
                    Pet = ownerAndPet.petName
                }
        );

    // Print the results.
    foreach (var obj in query)
    {
        Console.WriteLine(obj);
    }
}

// This code produces the following output:
//
// {Owner=Higa, Pet=Scruffy}
// {Owner=Higa, Pet=Sam}
// {Owner=Ashkenazi, Pet=Sugar}
// {Owner=Price, Pet=Scratches}
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))
    Next

    ' 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

注解

此方法通过使用延迟执行来实现。 即时返回值是一个对象,用于存储执行操作所需的所有信息。 除非对象通过直接调用其方法或在 foreach Visual C# 或 For Each Visual Basic 中使用来枚举对象GetEnumerator,否则不会执行此方法表示的查询。

当必须保留调用后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>>) 并导航回 TSource 对象 TCollection

在查询表达式语法中,初始子句转换为调用SelectMany后,每个from子句 (Visual C#) 或From子句 (Visual Basic) 。

另请参阅

适用于

SelectMany<TSource,TResult>(IEnumerable<TSource>, Func<TSource,IEnumerable<TResult>>)

将序列的每个元素投影到 IEnumerable<T> 并将结果序列合并为一个序列。

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

source 的元素类型。

TResult

selector 返回的序列元素的类型。

参数

source
IEnumerable<TSource>

一个要投影的值序列。

selector
Func<TSource,IEnumerable<TResult>>

应用于每个元素的转换函数。

返回

IEnumerable<TResult>

一个 IEnumerable<T>,其元素是对输入序列的每个元素调用一对多转换函数得到的结果。

例外

sourceselectornull

示例

下面的代码示例演示如何用于 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
 Sam
 Walker
 Sugar
 Scratches
 Diesel

 Using Select():
 Scruffy
 Sam

 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)
    Next

    ' 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)
        Next
    Next

    ' 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

注解

此方法通过使用延迟执行来实现。 即时返回值是一个对象,用于存储执行操作所需的所有信息。 除非对象通过直接调用其方法或在 foreach Visual C# 或 For Each Visual Basic 中使用来枚举对象GetEnumerator,否则不会执行此方法表示的查询。

该方法 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子句 (Visual C#) 或From子句 (Visual Basic) 。

另请参阅

适用于

SelectMany<TSource,TResult>(IEnumerable<TSource>, Func<TSource,Int32,IEnumerable<TResult>>)

将序列的每个元素投影到 IEnumerable<T> 并将结果序列合并为一个序列。 每个源元素的索引用于该元素的投影表。

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

source 的元素类型。

TResult

selector 返回的序列元素的类型。

参数

source
IEnumerable<TSource>

一个要投影的值序列。

selector
Func<TSource,Int32,IEnumerable<TResult>>

一个应用于每个源元素的转换函数;函数的第二个参数表示源元素的索引。

返回

IEnumerable<TResult>

一个 IEnumerable<T>,其元素是对输入序列的每个元素调用一对多转换函数得到的结果。

例外

sourceselectornull

示例

下面的代码示例演示如何用于 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)
    Next

    ' Display the output.
    Console.WriteLine(output.ToString())
End Sub

注解

此方法通过使用延迟执行来实现。 即时返回值是一个对象,用于存储执行操作所需的所有信息。 除非对象通过直接调用其方法或在 foreach Visual C# 或 For Each Visual Basic 中使用来枚举对象GetEnumerator,否则不会执行此方法表示的查询。

该方法 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 。 例如,如果元素按已知顺序运行,并且想要使用特定索引处的元素执行某些操作,这可能很有用。 如果要检索一个或多个元素的索引,它也很有用。

适用于