Enumerable.SelectMany Enumerable.SelectMany Enumerable.SelectMany Enumerable.SelectMany Method

定义

将序列的每个元素投影到 IEnumerable<T> 并将结果序列合并为一个序列。Projects each element of a sequence to an IEnumerable<T> and flattens the resulting sequences into one sequence.

重载

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

将序列的每个元素投影到 IEnumerable<T>,并将结果序列合并为一个序列,并对其中每个元素调用结果选择器函数。Projects each element of a sequence to an IEnumerable<T>, flattens the resulting sequences into one sequence, and invokes a result selector function on each element therein.

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

将序列的每个元素投影到 IEnumerable<T>,并将结果序列合并为一个序列,并对其中每个元素调用结果选择器函数。Projects each element of a sequence to an IEnumerable<T>, flattens the resulting sequences into one sequence, and invokes a result selector function on each element therein. 每个源元素的索引用于该元素的中间投影表。The index of each source element is used in the intermediate projected form of that element.

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

将序列的每个元素投影到 IEnumerable<T> 并将结果序列合并为一个序列。Projects each element of a sequence to an IEnumerable<T> and flattens the resulting sequences into one sequence.

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

将序列的每个元素投影到 IEnumerable<T> 并将结果序列合并为一个序列。Projects each element of a sequence to an IEnumerable<T>, and flattens the resulting sequences into one sequence. 每个源元素的索引用于该元素的投影表。The index of each source element is used in the projected form of that element.

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

将序列的每个元素投影到 IEnumerable<T>,并将结果序列合并为一个序列,并对其中每个元素调用结果选择器函数。Projects each element of a sequence to an IEnumerable<T>, flattens the resulting sequences into one sequence, and invokes a result selector function on each element therein.

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 的元素类型。The type of the elements of source.

TCollection

collectionSelector 收集的中间元素的类型。The type of the intermediate elements collected by collectionSelector.

TResult

结果序列的元素的类型。The type of the elements of the resulting sequence.

参数

source
IEnumerable<TSource>

一个要投影的值序列。A sequence of values to project.

collectionSelector
Func<TSource,IEnumerable<TCollection>>

应用于输入序列的每个元素的转换函数。A transform function to apply to each element of the input sequence.

resultSelector
Func<TSource,TCollection,TResult>

应用于中间序列的每个元素的转换函数。A transform function to apply to each element of the intermediate sequence.

返回

IEnumerable<TResult>

一个 IEnumerable<T>,其元素是通过以下方法得到的:对 source 的每个元素调用一对多转换函数 collectionSelector,然后将这些序列元素中的每一个元素及其相应的源元素映射到一个结果元素。An IEnumerable<T> whose elements are the result of invoking the one-to-many transform function collectionSelector on each element of source and then mapping each of those sequence elements and their corresponding source element to a result element.

异常

sourcecollectionSelectorresultSelectornullsource or collectionSelector or resultSelector is null.

示例

下面的代码示例演示如何使用SelectMany<TSource,TCollection,TResult>(IEnumerable<TSource>, Func<TSource,IEnumerable<TCollection>>, Func<TSource,TCollection,TResult>)对数组执行一对多投影, 并使用结果选择器函数将源序列中的每个对应元素保留在对的最终Select调用范围内。The following code example demonstrates how to use SelectMany<TSource,TCollection,TResult>(IEnumerable<TSource>, Func<TSource,IEnumerable<TCollection>>, Func<TSource,TCollection,TResult>) to perform a one-to-many projection over an array and use a result selector function to keep each corresponding element from the source sequence in scope for the final call to 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.
    MsgBox(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

注解

此方法是使用延迟执行实现的。This method is implemented by using deferred execution. 即时返回值是一个对象, 该对象存储执行操作所需的所有信息。The immediate return value is an object that stores all the information that is required to perform the action. 此方法表示的查询在枚举对象之前不会执行, 方法是直接调用其GetEnumerator方法, 或者通过在foreach视觉C#对象中For Each或在 Visual Basic 中使用。The query represented by this method is not executed until the object is enumerated either by calling its GetEnumerator method directly or by using foreach in Visual C# or For Each in 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>)发生的查询逻辑范围中时, 方法非常有用。The SelectMany<TSource,TCollection,TResult>(IEnumerable<TSource>, Func<TSource,IEnumerable<TCollection>>, Func<TSource,TCollection,TResult>) method is useful when you have to keep the elements of source in scope for query logic that occurs after the call to SelectMany<TSource,TCollection,TResult>(IEnumerable<TSource>, Func<TSource,IEnumerable<TCollection>>, Func<TSource,TCollection,TResult>). 有关代码示例,请参见“示例”部分。See the Example section for a code example. 如果TSource类型的对象与类型TCollection的对象之间存在双向关系, 即, 如果类型TCollection的对象提供了属性来检索TSource生成它的对象, 则不需要此的SelectMany<TSource,TCollection,TResult>(IEnumerable<TSource>, Func<TSource,IEnumerable<TCollection>>, Func<TSource,TCollection,TResult>)重载。If there is a bidirectional relationship between objects of type TSource and objects of type TCollection, that is, if an object of type TCollection provides a property to retrieve the TSource object that produced it, you do not need this overload of SelectMany<TSource,TCollection,TResult>(IEnumerable<TSource>, Func<TSource,IEnumerable<TCollection>>, Func<TSource,TCollection,TResult>). 相反, 你可以通过SelectMany<TSource,TResult>(IEnumerable<TSource>, Func<TSource,IEnumerable<TResult>>) TCollection对象使用并TSource向后导航到对象。Instead, you can use SelectMany<TSource,TResult>(IEnumerable<TSource>, Func<TSource,IEnumerable<TResult>>) and navigate back to the TSource object through the TCollection object.

在查询表达式语法中, from第一个子句C#(Visual From ) 或子句 (Visual Basic) 在第一次后转换为SelectMany对的调用。In query expression syntax, each from clause (Visual C#) or From clause (Visual Basic) after the initial one translates to an invocation of SelectMany.

另请参阅

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

将序列的每个元素投影到 IEnumerable<T>,并将结果序列合并为一个序列,并对其中每个元素调用结果选择器函数。Projects each element of a sequence to an IEnumerable<T>, flattens the resulting sequences into one sequence, and invokes a result selector function on each element therein. 每个源元素的索引用于该元素的中间投影表。The index of each source element is used in the intermediate projected form of that element.

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 的元素类型。The type of the elements of source.

TCollection

collectionSelector 收集的中间元素的类型。The type of the intermediate elements collected by collectionSelector.

TResult

结果序列的元素的类型。The type of the elements of the resulting sequence.

参数

source
IEnumerable<TSource>

一个要投影的值序列。A sequence of values to project.

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

一个应用于每个源元素的转换函数;函数的第二个参数表示源元素的索引。A transform function to apply to each source element; the second parameter of the function represents the index of the source element.

resultSelector
Func<TSource,TCollection,TResult>

应用于中间序列的每个元素的转换函数。A transform function to apply to each element of the intermediate sequence.

返回

IEnumerable<TResult>

一个 IEnumerable<T>,其元素是通过以下方法得到的:对 source 的每个元素调用一对多转换函数 collectionSelector,然后将这些序列元素中的每一个元素及其相应的源元素映射到一个结果元素。An IEnumerable<T> whose elements are the result of invoking the one-to-many transform function collectionSelector on each element of source and then mapping each of those sequence elements and their corresponding source element to a result element.

异常

sourcecollectionSelectorresultSelectornullsource or collectionSelector or resultSelector is null.

注解

此方法是使用延迟执行实现的。This method is implemented by using deferred execution. 即时返回值是一个对象, 该对象存储执行操作所需的所有信息。The immediate return value is an object that stores all the information that is required to perform the action. 此方法表示的查询在枚举对象之前不会执行, 方法是直接调用其GetEnumerator方法, 或者通过在foreach视觉C#对象中For Each或在 Visual Basic 中使用。The query represented by this method is not executed until the object is enumerated either by calling its GetEnumerator method directly or by using foreach in Visual C# or For Each in 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>)发生的查询逻辑范围中时, 方法非常有用。The SelectMany<TSource,TCollection,TResult>(IEnumerable<TSource>, Func<TSource,Int32,IEnumerable<TCollection>>, Func<TSource,TCollection,TResult>) method is useful when you have to keep the elements of source in scope for query logic that occurs after the call to SelectMany<TSource,TCollection,TResult>(IEnumerable<TSource>, Func<TSource,Int32,IEnumerable<TCollection>>, Func<TSource,TCollection,TResult>). 有关代码示例,请参见“示例”部分。See the Example section for a code example. 如果TSource类型的对象与类型TCollection的对象之间存在双向关系, 即, 如果类型TCollection的对象提供了属性来检索TSource生成它的对象, 则不需要此的SelectMany<TSource,TCollection,TResult>(IEnumerable<TSource>, Func<TSource,Int32,IEnumerable<TCollection>>, Func<TSource,TCollection,TResult>)重载。If there is a bidirectional relationship between objects of type TSource and objects of type TCollection, that is, if an object of type TCollection provides a property to retrieve the TSource object that produced it, you do not need this overload of SelectMany<TSource,TCollection,TResult>(IEnumerable<TSource>, Func<TSource,Int32,IEnumerable<TCollection>>, Func<TSource,TCollection,TResult>). 相反, 你可以通过SelectMany<TSource,TResult>(IEnumerable<TSource>, Func<TSource,Int32,IEnumerable<TResult>>) TCollection对象使用并TSource向后导航到对象。Instead, you can use SelectMany<TSource,TResult>(IEnumerable<TSource>, Func<TSource,Int32,IEnumerable<TResult>>) and navigate back to the TSource object through the TCollection object.

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

将序列的每个元素投影到 IEnumerable<T> 并将结果序列合并为一个序列。Projects each element of a sequence to an IEnumerable<T> and flattens the resulting sequences into one sequence.

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 的元素类型。The type of the elements of source.

TResult

selector 返回的序列元素的类型。The type of the elements of the sequence returned by selector.

参数

source
IEnumerable<TSource>

一个要投影的值序列。A sequence of values to project.

selector
Func<TSource,IEnumerable<TResult>>

应用于每个元素的转换函数。A transform function to apply to each element.

返回

IEnumerable<TResult>

一个 IEnumerable<T>,其元素是对输入序列的每个元素调用一对多转换函数得到的结果。An IEnumerable<T> whose elements are the result of invoking the one-to-many transform function on each element of the input sequence.

异常

sourceselectornullsource or selector is null.

示例

下面的代码示例演示如何使用SelectMany<TSource,TResult>(IEnumerable<TSource>, Func<TSource,IEnumerable<TResult>>)对数组执行一对多投影。The following code example demonstrates how to use SelectMany<TSource,TResult>(IEnumerable<TSource>, Func<TSource,IEnumerable<TResult>>) to perform a one-to-many projection over an array.

           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.
    MsgBox(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

注解

此方法是使用延迟执行实现的。This method is implemented by using deferred execution. 即时返回值是一个对象, 该对象存储执行操作所需的所有信息。The immediate return value is an object that stores all the information that is required to perform the action. 此方法表示的查询在枚举对象之前不会执行, 方法是直接调用其GetEnumerator方法, 或者通过在foreach视觉C#对象中For Each或在 Visual Basic 中使用。The query represented by this method is not executed until the object is enumerated either by calling its GetEnumerator method directly or by using foreach in Visual C# or For Each in Visual Basic.

方法枚举输入序列, 使用转换函数将每个元素映射IEnumerable<T>到, 然后枚举并生成每个此类IEnumerable<T>对象的元素。 SelectMany<TSource,TResult>(IEnumerable<TSource>, Func<TSource,IEnumerable<TResult>>)The SelectMany<TSource,TResult>(IEnumerable<TSource>, Func<TSource,IEnumerable<TResult>>) method enumerates the input sequence, uses a transform function to map each element to an IEnumerable<T>, and then enumerates and yields the elements of each such IEnumerable<T> object. 也就是说, selector将调用的每个source元素, 并返回一个值序列。That is, for each element of source, selector is invoked and a sequence of values is returned. SelectMany<TSource,TResult>(IEnumerable<TSource>, Func<TSource,IEnumerable<TResult>>)然后, 将这一二维集合合并为一维IEnumerable<T>并返回它。SelectMany<TSource,TResult>(IEnumerable<TSource>, Func<TSource,IEnumerable<TResult>>) then flattens this two-dimensional collection of collections into a one-dimensional IEnumerable<T> and returns it. 例如, 如果查询SelectMany<TSource,TResult>(IEnumerable<TSource>, Func<TSource,IEnumerable<TResult>>)使用获取数据库中每个客户的订单 (类型Order为), 则结果为类型IEnumerable<Order>为C#或IEnumerable(Of Order) Visual Basic 中。For example, if a query uses SelectMany<TSource,TResult>(IEnumerable<TSource>, Func<TSource,IEnumerable<TResult>>) to obtain the orders (of type Order) for each customer in a database, the result is of type IEnumerable<Order> in C# or IEnumerable(Of Order) in Visual Basic. 如果查询使用Select来获取订单, 则不会合并订单集合的集合, 结果类型IEnumerable<List<Order>>为C#或IEnumerable(Of List(Of Order)) Visual Basic 中。If instead the query uses Select to obtain the orders, the collection of collections of orders is not combined and the result is of type IEnumerable<List<Order>> in C# or IEnumerable(Of List(Of Order)) in Visual Basic.

在查询表达式语法中, from第一个子句C#(Visual From ) 或子句 (Visual Basic) 在第一次后转换为SelectMany对的调用。In query expression syntax, each from clause (Visual C#) or From clause (Visual Basic) after the initial one translates to an invocation of SelectMany.

另请参阅

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

将序列的每个元素投影到 IEnumerable<T> 并将结果序列合并为一个序列。Projects each element of a sequence to an IEnumerable<T>, and flattens the resulting sequences into one sequence. 每个源元素的索引用于该元素的投影表。The index of each source element is used in the projected form of that element.

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 的元素类型。The type of the elements of source.

TResult

selector 返回的序列元素的类型。The type of the elements of the sequence returned by selector.

参数

source
IEnumerable<TSource>

一个要投影的值序列。A sequence of values to project.

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

一个应用于每个源元素的转换函数;函数的第二个参数表示源元素的索引。A transform function to apply to each source element; the second parameter of the function represents the index of the source element.

返回

IEnumerable<TResult>

一个 IEnumerable<T>,其元素是对输入序列的每个元素调用一对多转换函数得到的结果。An IEnumerable<T> whose elements are the result of invoking the one-to-many transform function on each element of an input sequence.

异常

sourceselectornullsource or selector is null.

示例

下面的代码示例演示如何使用SelectMany<TSource,TResult>(IEnumerable<TSource>, Func<TSource,Int32,IEnumerable<TResult>>)对数组执行一对多投影, 并使用每个外部元素的索引。The following code example demonstrates how to use SelectMany<TSource,TResult>(IEnumerable<TSource>, Func<TSource,Int32,IEnumerable<TResult>>) to perform a one-to-many projection over an array and use the index of each outer element.

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.
    MsgBox(output.ToString())
End Sub

注解

此方法是使用延迟执行实现的。This method is implemented by using deferred execution. 即时返回值是一个对象, 该对象存储执行操作所需的所有信息。The immediate return value is an object that stores all the information that is required to perform the action. 此方法表示的查询在枚举对象之前不会执行, 方法是直接调用其GetEnumerator方法, 或者通过在foreach视觉C#对象中For Each或在 Visual Basic 中使用。The query represented by this method is not executed until the object is enumerated either by calling its GetEnumerator method directly or by using foreach in Visual C# or For Each in Visual Basic.

方法枚举输入序列, 使用转换函数将每个元素映射IEnumerable<T>到, 然后枚举并生成每个此类IEnumerable<T>对象的元素。 SelectMany<TSource,TResult>(IEnumerable<TSource>, Func<TSource,Int32,IEnumerable<TResult>>)The SelectMany<TSource,TResult>(IEnumerable<TSource>, Func<TSource,Int32,IEnumerable<TResult>>) method enumerates the input sequence, uses a transform function to map each element to an IEnumerable<T>, and then enumerates and yields the elements of each such IEnumerable<T> object. 也就是说, selector将调用的每个source元素, 并返回一个值序列。That is, for each element of source, selector is invoked and a sequence of values is returned. SelectMany<TSource,TResult>(IEnumerable<TSource>, Func<TSource,Int32,IEnumerable<TResult>>)然后, 将这一二维集合合并为一维IEnumerable<T>并返回它。SelectMany<TSource,TResult>(IEnumerable<TSource>, Func<TSource,Int32,IEnumerable<TResult>>) then flattens this two-dimensional collection of collections into a one-dimensional IEnumerable<T> and returns it. 例如, 如果查询SelectMany<TSource,TResult>(IEnumerable<TSource>, Func<TSource,Int32,IEnumerable<TResult>>)使用获取数据库中每个客户的订单 (类型Order为), 则结果为类型IEnumerable<Order>为C#或IEnumerable(Of Order) Visual Basic 中。For example, if a query uses SelectMany<TSource,TResult>(IEnumerable<TSource>, Func<TSource,Int32,IEnumerable<TResult>>) to obtain the orders (of type Order) for each customer in a database, the result is of type IEnumerable<Order> in C# or IEnumerable(Of Order) in Visual Basic. 如果查询使用Select来获取订单, 则不会合并订单集合的集合, 结果类型IEnumerable<List<Order>>为C#或IEnumerable(Of List(Of Order)) Visual Basic 中。If instead the query uses Select to obtain the orders, the collection of collections of orders is not combined and the result is of type IEnumerable<List<Order>> in C# or IEnumerable(Of List(Of Order)) in Visual Basic.

selector表示要处理的元素的第一个参数。The first argument to selector represents the element to process. 第二个参数selector , 用于表示源序列中该元素的从零开始的索引。The second argument to selector represents the zero-based index of that element in the source sequence. 例如, 如果元素处于已知顺序, 并且你想要对特定索引处的元素执行某些操作, 则这会很有用。This can be useful if the elements are in a known order and you want to do something with an element at a particular index, for example. 如果要检索一个或多个元素的索引, 此方法也会很有用。It can also be useful if you want to retrieve the index of one or more elements.

适用于