次の方法で共有


射影操作

更新 : 2007 年 11 月

射影とは、オブジェクトを新しい形式に変換する操作のことを言います。この新しい形式は多くの場合、後で使用するプロパティだけで構成されたものになります。射影を使用することで、各オブジェクトからビルドされる新しい型を構築することができます。プロパティを射影し、それに対して数値演算関数を実行することができます。また、元のオブジェクトを変更せずに射影することもできます。

次のセクションに、射影を実行する標準クエリ演算子メソッドの一覧を示します。

メソッド

メソッド名

説明

C# のクエリ式の構文

Visual Basic のクエリ式の構文

詳細情報

Select

変換関数に基づく値を射影します。

select

Select

Enumerable.Select

Queryable.Select

SelectMany

変換関数に基づく値のシーケンスを射影し、それを 1 つのシーケンスに平坦化します。

複数の from 句を使用します。

複数の From 句を使用します。

Enumerable.SelectMany

Queryable.SelectMany

クエリ式の構文の例

オン

次の例では、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() は、各ソース値ごとに結果値を 1 つ生成します。したがって、結果全体は、ソース コレクションと同じ数の要素を持つコレクションになります。一方、SelectMany() は、各ソース値から、連結されたサブ コレクションを含む 1 つの総合的な結果を生成します。SelectMany() に引数として渡される変換関数は、各ソース値ごとに列挙可能な値のシーケンスを返す必要があります。この列挙可能なシーケンスはその後 SelectMany() によって連結され、1 つの大きなシーケンスを作成します。

これら 2 つのメソッドのアクションの概念上の相違を次の 2 つの図に示します。どちらの場合も、セレクタ (変換) 関数が各ソース値から花の配列を選択すると仮定します。

ソース コレクションと同じ数の要素を持つコレクションを Select() が返すしくみを次の図に示します。

Select() のアクションの概念を示す図

SelectMany() が中間配列シーケンスを、各中間配列の値を含む最終的な結果値に連結するしくみを次の図に示します。

SelectMany() のアクションを示すグラフィック。

コード例

次の例は、Select()SelectMany() の動作を比較しています。コードは、ソース コレクションの花の名前の各リストから最初の 2 つの項目を取って "花束" を作成します。この例では、変換関数 Select<TSource, TResult>(IEnumerable<TSource>, Func<TSource, TResult>) が使用する "単一の値" 自体が値のコレクションになっています。各サブ シーケンスで文字列を列挙するには追加の foreach (Visual Basic では For Each) ループが必要です。

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

}

射影の方法についての詳細情報

Topic Location
方法 : グループを使用して 1 つのファイルを複数のファイルに分割する (LINQ) 統合言語クエリ (LINQ: Language-Integrated Query)
方法 : 複数のソースからオブジェクト コレクションにデータを設定する (LINQ) 統合言語クエリ (LINQ: Language-Integrated Query)
select 句 (C# リファレンス) C# プログラマーズ リファレンス
方法 : LINQ の結合を使用してデータを結合する (Visual Basic) Visual Basic 言語リファレンス
方法 : LINQ クエリ結果を特定の型で返す (Visual Basic) Visual Basic 言語リファレンス
select 句 (C# リファレンス) dv_csref
方法: グループを使用して 1 つのファイルを複数のファイルに分割する (LINQ) dv_Linq
方法: 複数のソースからオブジェクト コレクションにデータを設定する (LINQ) dv_Linq
方法 : LINQ の結合を使用してデータを結合する (Visual Basic) dv_vbalr
方法 : LINQ クエリ結果を特定の型で返す (Visual Basic) dv_vbalr
方法: グループを使用して 1 つのファイルを複数のファイルに分割する (LINQ) dv_Linq
方法: 複数のソースからオブジェクト コレクションにデータを設定する (LINQ) dv_Linq
select 句 (C# リファレンス) dv_csref
方法 : LINQ の結合を使用してデータを結合する (Visual Basic) dv_vbalr
方法 : LINQ クエリ結果を特定の型で返す (Visual Basic) dv_vbalr

参照

概念

標準クエリ演算子の概要

参照

select 句 (C# リファレンス)

Select 句 (Visual Basic)

System.Linq