Enumerable.SelectMany 方法
定義
重要
部分資訊涉及發行前產品,在發行之前可能會有大幅修改。 Microsoft 對此處提供的資訊,不做任何明確或隱含的瑕疵擔保。
將序列的每個項目都投影成 IEnumerable<T>,並將產生的序列簡化成單一序列。
多載
SelectMany<TSource,TCollection,TResult>(IEnumerable<TSource>, Func<TSource,IEnumerable<TCollection>>, Func<TSource,TCollection,TResult>) |
將序列的每個項目投影為 IEnumerable<T>、將產生的序列簡化成單一序列,並對其中的每個項目叫用結果選取器函式。 |
SelectMany<TSource,TCollection,TResult>(IEnumerable<TSource>, Func<TSource,Int32,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,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<T>,其項目是執行下列動作後所產生的結果:對 collectionSelector
的各個項目叫用一對多轉換函式 source
,然後再將每個序列項目及其對應的來源項目對應到結果項目。
例外狀況
source
、collectionSelector
或 resultSelector
為 null
。
範例
下列程式碼範例示範如何使用 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
C# 或 Visual Basic 中使用 foreach
來列舉物件,否則 For Each
不會執行這個方法所表示的查詢。
當您必須針對呼叫 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
子句都會 (C#) 或 From
子句 (Visual Basic) 。
另請參閱
適用於
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<T>,其項目是執行下列動作後所產生的結果:對 collectionSelector
的各個項目叫用一對多轉換函式 source
,然後再將每個序列項目及其對應的來源項目對應到結果項目。
例外狀況
source
、collectionSelector
或 resultSelector
為 null
。
備註
此方法是使用延後執行來實作。 立即傳回值是物件,可儲存執行動作所需的所有資訊。 除非直接在 GetEnumerator
C# 或 Visual Basic 中使用 foreach
來列舉物件,否則 For Each
不會執行這個方法所表示的查詢。
當您必須針對呼叫 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,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<T>,其項目是在輸入序列的各個項目上叫用一對多轉換函式所產生的結果。
例外狀況
source
或 selector
為 null
。
範例
下列程式碼範例示範如何使用 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
C# 或 Visual Basic 中使用 foreach
來列舉物件,否則 For Each
不會執行這個方法所表示的查詢。
方法 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) 。
另請參閱
適用於
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<T>,其項目是對輸入序列中各個項目叫用一對多轉換函式後所產生的結果。
例外狀況
source
或 selector
為 null
。
範例
下列程式碼範例示範如何使用 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
C# 或 Visual Basic 中使用 foreach
來列舉物件,否則 For Each
不會執行這個方法所表示的查詢。
方法 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
表示來源序列中該元素之以零起始的索引。 例如,如果元素處於已知順序,而且您想要在特定索引處使用元素執行某些動作,這非常有用。 如果您想要擷取一或多個元素的索引,它也很有用。
適用於
意見反應
https://aka.ms/ContentUserFeedback。
即將登場:在 2024 年,我們將逐步淘汰 GitHub 問題作為內容的意見反應機制,並將它取代為新的意見反應系統。 如需詳細資訊,請參閱:提交並檢視相關的意見反應