投影作業
投影係指將物件轉換為新表單的作業,而轉換後的新表單中通常只包含後續作業中所要使用的屬性。 您可以利用投影來建構從每個物件所建置 (Build) 的新型別。 您可以投影屬性,並對其執行數學函式。 您也可以投影原始物件,而不變更該物件。
下節會列出執行投影的標準查詢運算子方法。
方法
方法名稱 |
說明 |
C# 查詢運算式語法 |
Visual Basic 查詢運算式語法 |
詳細資訊 |
---|---|---|---|---|
Select |
投影以轉換函式為基礎的值。 |
select |
Select |
|
SelectMany |
投影以轉換函式為基礎的值序列,然後將它們簡化成單一序列。 |
使用多個 from 子句 |
使用多個 From 子句 |
查詢運算式語法範例
Select
下列範例使用 C# 中的 select 子句或 Visual Basic 中的 Select 子句,投影字串清單中各字串的第一個字母。
Dim words = New List(Of String) From {"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
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
下列範例使用 C# 中的多個 from 子句或 Visual Basic 中的 From 子句,投影字串清單中各字串的每個單字。
Dim phrases = New List(Of String) From {"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
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<TSource, TResult>(IEnumerable<TSource>, Func<TSource, TResult>) 使用的「單一值」本身是值的集合。 這需要有額外的 foreach (在 Visual Basic 中為 For Each) 迴圈 (Loop) 才能列舉每個子序列中的每個字串。
Class Bouquet
Public Flowers As List(Of String)
End Class
Sub SelectVsSelectMany()
Dim bouquets = New List(Of Bouquet) From {
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
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
*/
}
請參閱
工作
HOW TO:使用 Joins 以 LINQ 合併資料 (Visual Basic)
HOW TO:將 LINQ 查詢結果當做特定型別傳回 (Visual Basic)