投影運算

投影(Projection)運算是指將對象轉換為一種新形式的操作,該形式通常只包含那些將隨後使用的屬性。通過使用投影,您可以構建依據每個對象生成的新類型。

基本信息

基本信息

投影(Projection)運算是指將對象轉換為一種新形式的操作,該形式通常只包含那些將隨後使用的屬性。通過使用投影,您可以構建依據每個對象生成的新類型。您可以映射屬性,並對該屬性執行數學函式。還可以在不更改原始對象的情況下映射該對象。簡單地說,便是在關係中選擇某些屬性列。

下面一節中列出了執行投影的標準查詢運算符方法。

方法

方法名

說明

C# 查詢表達式語法

Visual Basic 查詢表達式語法

更多信息

Select

映射基於轉換函式的值。

select

Select

Enumerable..::.Select

Queryable..::.Select

SelectMany

映射基於轉換函式的值序列,然後將它們展平為一個序列。

使用多個 from 子句

使用多個 From 子句

Enumerable..::.SelectMany

Queryable..::.SelectMany

查詢表達式語法示例

Select

下面的示例使用 C# 中的 select 子句或 Visual Basic 中的 Select 子句來映射字元串列表中每個字元串的第一個字母。

Visual Basic 複製代碼Dim words As New List(Of String)(New String() {"an", "apple", "a", "day"})

Dim query = From word In words _

Select word.Substring(0, 1)

Dim sb As New System.Text.StringBuilder()

For Each letter As String In query

sb.AppendLine(letter)

Next

' Display the output.

MsgBox(sb.ToString())

' This code produces the following output:

' a

' a

' a

' d

C# 複製代碼List<string> words = new List<string>() { "an", "apple", "a", "day" };

var query = from word in words

select word.Substring(0, 1);

foreach (string s in query)

Console.WriteLine(s);

/* This code produces the following output:

a

a

a

d

*/

SelectMany

下面的示例使用多個 from 子句(在 C# 中)或 From 子句(在 Visual Basic 中)來映射字元串列表中每個字元串中的每個單詞。

Visual Basic 複製代碼Dim phrases As New List(Of String)(New String() {"an apple a day", "the quick brown fox"})

Dim query = From phrase In phrases _

From word In phrase.Split(" "c) _

Select word

Dim sb As New System.Text.StringBuilder()

For Each str As String In query

sb.AppendLine(str)

Next

' Display the output.

MsgBox(sb.ToString())

' This code produces the following output:

' an

' apple

' a

' day

' the

' quick

' brown

' fox

C# 複製代碼List<string> phrases = new List<string>() { "an apple a day", "the quick brown fox" };

var query = from phrase in phrases

from word in phrase.Split(' ')

select word;

foreach (string s in query)

Console.WriteLine(s);

/* This code produces the following output:

an

apple

a

day

the

quick

brown

fox

*/

Select 與 SelectMany

Select() 和 SelectMany() 的工作都是依據源值生成一個或多個結果值。Select() 為每個源值生成一個結果值。因此,總體結果是一個與源集合具有相同元素數目的集合。與之相反,SelectMany() 將生成單一總體結果,其中包含來自每個源值的串聯子集合。作為參數傳遞到 SelectMany() 的轉換函式必須為每個源值返回一個可枚舉值序列。然後,SelectMany() 將串聯這些可枚舉序列以創建一個大的序列。

下面兩個插圖演示了這兩個方法的操作之間的概念性區別。在每種情況下,假定選擇器(轉換)函式從每個源值中選擇一個由花卉數據組成的數組。

下圖描述 Select() 如何返回一個與源集合具有相同元素數目的集合。

下圖描述 SelectMany() 如何將中間數組序列串聯為一個最終結果值,其中包含每箇中間數組中的每個值。

代碼示例

下面的示例比較 Select() 和 SelectMany() 的行為。代碼將通過從源集合的每個花卉名稱列表中提取前兩項來創建一個“花束”。在此示例中,轉換函式 Select<(Of <(TSource, TResult>)>)(IEnumerable<(Of <(TSource>)>), Func<(Of <(TSource, TResult>)>)) 使用的“單一值”本身就是一個值集合。這需要額外的 foreach(Visual Basic 中為 For Each)循環,以便枚舉每個子序列中的每個字元串。

Visual Basic 複製代碼Class Bouquet

Public Flowers As List(Of String)

End Class

Sub SelectVsSelectMany()

Dim bouquets As New List(Of Bouquet)(New Bouquet() { _

New Bouquet With {.Flowers = New List(Of String)(New String() {"sunflower", "daisy", "daffodil", "larkspur"})}, _

New Bouquet With {.Flowers = New List(Of String)(New String() {"tulip", "rose", "orchid"})}, _

New Bouquet With {.Flowers = New List(Of String)(New String() {"gladiolis", "lily", "snapdragon", "aster", "protea"})}, _

New Bouquet With {.Flowers = New List(Of String)(New String() {"larkspur", "lilac", "iris", "dahlia"})}})

Dim output As New System.Text.StringBuilder

' Select()

Dim query1 = bouquets.Select(Function(b) b.Flowers)

output.AppendLine("Using Select():")

For Each flowerList In query1

For Each str As String In flowerList

其他信息

output.AppendLine(str)

Next

Next

' SelectMany()

Dim query2 = bouquets.SelectMany(Function(b) b.Flowers)

output.AppendLine(vbCrLf & "Using SelectMany():")

For Each str As String In query2

output.AppendLine(str)

Next

' Display the output

MsgBox(output.ToString())

' This code produces the following output:

'

' Using Select():

' sunflower

' daisy

' daffodil

' larkspur

' tulip

' rose

' orchid

' gladiolis

' lily

' snapdragon

' aster

' protea

' larkspur

' lilac

' iris

' dahlia

' Using SelectMany()

' sunflower

' daisy

' daffodil

' larkspur

' tulip

' rose

' orchid

' gladiolis

' lily

' snapdragon

' aster

' protea

' larkspur

' lilac

' iris

' dahlia

End Sub

C# 複製代碼class Bouquet

{

public List<string> Flowers { get; set; }

}

static void SelectVsSelectMany()

{

List<Bouquet> bouquets = new List<Bouquet>() {

new Bouquet { Flowers = new List<string> { "sunflower", "daisy", "daffodil", "larkspur" }},

new Bouquet{ Flowers = new List<string> { "tulip", "rose", "orchid" }},

new Bouquet{ Flowers = new List<string> { "gladiolis", "lily", "snapdragon", "aster", "protea" }},

new Bouquet{ Flowers = new List<string> { "larkspur", "lilac", "iris", "dahlia" }}

};

// *********** Select ***********

IEnumerable<List<string>> query1 = bouquets.Select(bq => bq.Flowers);

// ********* SelectMany *********

IEnumerable<string> query2 = bouquets.SelectMany(bq => bq.Flowers);

Console.WriteLine("Results by using Select():");

// Note the extra foreach loop here.

foreach (IEnumerable<String> collection in query1)

foreach (string item in collection)

Console.WriteLine(item);

Console.WriteLine("\nResults by using SelectMany():");

foreach (string item in query2)

Console.WriteLine(item);

/* This code produces the following output:

Results by using Select():

sunflower

daisy

daffodil

larkspur

tulip

rose

orchid

gladiolis

lily

snapdragon

aster

protea

larkspur

lilac

iris

dahlia

Results by using SelectMany():

sunflower

daisy

daffodil

larkspur

tulip

rose

orchid

gladiolis

lily

snapdragon

aster

protea

larkspur

lilac

iris

dahlia

*/

}

相關詞條

相關搜尋

熱門詞條

聯絡我們