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>,其項目是執行下列動作後所產生的結果:對 collectionSelector 的各個項目叫用一對多轉換函式 source,然後再將每個序列項目及其對應的來源項目對應到結果項目。

例外狀況

sourcecollectionSelectorresultSelectornull

備註

此方法是使用延後執行來實作。 立即傳回值是物件,可儲存執行動作所需的所有資訊。 除非直接在 GetEnumerator Visual C# 中或使用 Visual C# 或 Visual Basic 來列舉物件,否則 For Each 不會執行這個方法 foreach 所表示的查詢。

當您必須針對呼叫 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 別的物件之間有雙向關聯性,也就是說,如果 型 TCollection 別的物件提供屬性來擷取 TSource 產生的物件,則您不需要這個多載。 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>>) 並巡覽回 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>,其項目是執行下列動作後所產生的結果:對 collectionSelector 的各個項目叫用一對多轉換函式 source,然後再將每個序列項目及其對應的來源項目對應到結果項目。

例外狀況

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

備註

此方法是使用延後執行來實作。 立即傳回值是物件,可儲存執行動作所需的所有資訊。 除非直接在 GetEnumerator Visual C# 中或使用 Visual C# 或 Visual Basic 來列舉物件,否則 For Each 不會執行這個方法 foreach 所表示的查詢。

當您必須針對呼叫 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 別的物件之間有雙向關聯性,也就是說,如果 型 TCollection 別的物件提供屬性來擷取 TSource 產生的物件,則您不需要這個多載。 SelectMany<TSource,TCollection,TResult>(IEnumerable<TSource>, Func<TSource,IEnumerable<TCollection>>, Func<TSource,TCollection,TResult>) 相反地,您可以透過 物件使用 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

備註

這個方法是使用延後執行來實作。 立即傳回值是一個物件,會儲存執行動作所需的所有資訊。 除非直接呼叫其 GetEnumerator 方法或在 Visual C# For Each 或 Visual Basic 中使用 foreach 來列舉物件,否則不會執行這個方法所代表的查詢。

方法 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

備註

這個方法是使用延後執行來實作。 立即傳回值是一個物件,會儲存執行動作所需的所有資訊。 除非直接呼叫其 GetEnumerator 方法或在 Visual C# For Each 或 Visual Basic 中使用 foreach 來列舉物件,否則不會執行這個方法所代表的查詢。

方法 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 表示來源序列中該元素之以零起始的索引。 例如,如果元素處於已知順序,而且您想要在特定索引處使用元素執行某些動作,這非常有用。 如果您想要擷取一或多個元素的索引,它也很有用。

適用於