Compartir vía


Operaciones de proyección (Visual Basic)

El término "proyección" hace referencia a la operación de transformar un objeto en una nueva forma que, a menudo, consta solo de aquellas propiedades que se usarán posteriormente. Utilizando la proyección, puede construir un tipo nuevo creado a partir de cada objeto. Se puede proyectar una propiedad y realizar una función matemática en ella. También puede proyectar el objeto original sin cambiarlo.

Los métodos del operador de consulta estándar que realizan proyecciones se indican en la sección siguiente.

Métodos

Nombre del método Descripción Sintaxis de expresiones de consulta de Visual Basic Más información
Seleccionar Proyecta valores basados en una función de transformación. Select Enumerable.Select

Queryable.Select
SelectMany Proyecta secuencias de valores que se basan en una función de transformación y después los convierte en una secuencia. Use varias cláusulas From Enumerable.SelectMany

Queryable.SelectMany
Zip Genera una secuencia de tuplas con elementos a partir de dos o tres secuencias especificadas. No aplicable. Enumerable.Zip
Queryable.Zip

Ejemplos de sintaxis de expresiones de consulta

Seleccionar

En el ejemplo siguiente se usa la cláusula Select para proyectar la primera letra de cada cadena de una lista de cadenas.

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

En el ejemplo siguiente se usan varias cláusulas From para proyectar cada palabra de todas las cadenas de una lista de cadenas.

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 frente a SelectMany

La función tanto de Select() como de SelectMany() consiste en generar un valor (o valores) de resultado a partir de valores de origen. Select() genera un valor de resultado para cada valor de origen. El resultado global, por tanto, es una colección que tiene el mismo número de elementos que la colección de origen. En cambio, SelectMany() genera un resultado global único que contiene subcolecciones concatenadas procedentes de cada valor de origen. La función de transformación que se pasa como argumento a SelectMany() debe devolver una secuencia enumerable de valores para cada valor de origen. Luego, SelectMany() concatena estas secuencias enumerables para crear una secuencia de gran tamaño.

Las dos ilustraciones siguientes muestran la diferencia conceptual entre las acciones de estos dos métodos. En cada caso, se supone que la función de selector (transformación) selecciona la matriz de flores de cada valor de origen.

En esta ilustración se muestra cómo Select() devuelve una colección que tiene el mismo número de elementos que la colección de origen.

Graphic that shows the action of Select()

En esta ilustración se muestra cómo SelectMany() concatena la secuencia intermedia de matrices en un valor de resultado final que contiene cada uno de los valores de todas las matrices intermedias.

Graphic showing the action of SelectMany().

Ejemplo de código

En el ejemplo siguiente se compara el comportamiento de Select() y SelectMany(). El código crea un "ramo" de flores tomando los elementos de cada lista de nombres de flores de la colección de origen. En este ejemplo, el "valor único" que la función de transformación Select<TSource,TResult>(IEnumerable<TSource>, Func<TSource,TResult>) usa es una colección de valores. Para ello, se requiere el bucle adicional For Each a fin de enumerar cada una de las cadenas de cada subsecuencia.

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

Consulte también