射影操作 (Visual Basic)
射影とは、オブジェクトを、必要なプロパティだけで構成された別の形式に変換する操作のことをいいます。 射影を使用することにより、個々のオブジェクトから構築された新しい型を作成できます。 プロパティを投影し、それに対して数値演算関数を実行できます。 また、元のオブジェクトを変更せずに射影することもできます。
次のセクションでは、射影を実行する標準クエリ演算子メソッドの一覧を示します。
メソッド
メソッド名 | 説明 | Visual Basic のクエリ式の構文 | 説明 |
---|---|---|---|
選択 | 変換関数に基づいて値を射影します。 | Select |
Enumerable.Select Queryable.Select |
SelectMany | 変換関数に基づいて値のシーケンスを射影し、それを 1 つのシーケンスに平坦化します。 | 複数の From 句を使用 |
Enumerable.SelectMany Queryable.SelectMany |
Zip | 指定された 2 つから 3 つのシーケンスの要素を持つタプルのシーケンスを生成します。 | 該当なし。 | Enumerable.Zip Queryable.Zip |
クエリ式の構文例
選択
次の例では、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
SelectMany
次の例では、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
Select と SelectMany の比較
Select()
と SelectMany()
の機能はどちらも、ソース値から結果値 (複数も可) を生成することです。 Select()
は、ソース値ごとに結果値を 1 つ生成します。 そのため、結果全体は、ソース コレクションと同じ数の要素を持つ 1 つのコレクションになります。 これに対し、SelectMany()
は、各ソース値から、連結されたサブコレクションを含む 1 つの総合的な結果を生成します。 SelectMany()
に引数として渡される変換関数は、ソース値ごとに列挙可能な値のシーケンスを返す必要があります。 この列挙可能なシーケンスは SelectMany()
によって連結されて、1 つの大きなシーケンスが作成されます。
これら 2 つのメソッドのアクションの概念的な違いを次の 2 つの図に示します。 どちらも、セレクター (変換) 関数が各ソース値から花の配列を選択することを想定しています。
次の図は、Select()
がソース コレクションと同じ数の要素を持つコレクションを返すしくみを示しています。
次の図は、SelectMany()
が中間配列シーケンスを、各中間配列の値を含む最終的な結果値に連結するしくみを示しています。
コード例
次の例は、Select()
と SelectMany()
の動作を比較しています。 コードは、ソース コレクションの花の名前の各リストから項目を取って "花束" を作成します。 この例では、変換関数 Select<TSource,TResult>(IEnumerable<TSource>, Func<TSource,TResult>) が使用する "単一の値" 自体が値のコレクションになっています。 各サブ シーケンスで各文字列を列挙するために追加の For Each
ループを使用しています。
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
関連項目
.NET