共用方式為


投影作業

更新:2007 年 11 月

投影係指將物件轉換為新表單的作業,而轉換後的新表單中通常只包含後續作業中所要使用的屬性。您可以利用投影來建構從每個物件所建置 (Build) 的新型別。您可以投影屬性,並對其執行數學函式。您也可以投影原始物件,而不變更該物件。

下節會列出執行投影的標準查詢運算子方法。

方法

方法名稱

說明

C# 查詢運算式語法

Visual Basic 查詢運算式語法

詳細資訊

Select

投影以轉換函式為基礎的值。

select

Select

Enumerable.Select

Queryable.Select

SelectMany

投影以轉換函式為基礎的值序列,然後將它們簡化成單一序列。

使用多個 from 子句

使用多個 From 子句

Enumerable.SelectMany

Queryable.SelectMany

查詢運算式語法範例

Select

下列範例使用 C# 中的 select 子句或 Visual Basic 中的 Select 子句,投影字串清單中各字串的第一個字母。

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

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

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() 如何傳回與來源集合具有相同項目數目的集合。

Select() 之動作的概念圖例

下圖說明 SelectMany() 如何將中繼陣列序列串連成內含各中繼陣列中每個值的單一最終結果值。

顯示 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 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
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
    */

}

進一步了解如何投影

請參閱

概念

標準查詢運算子概觀

參考

select 子句 (C# 參考)

Select 子句 (Visual Basic)

System.Linq