Operaciones de proyección (C#)Projection Operations (C#)

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.Projection refers to the operation of transforming an object into a new form that often consists only of those properties that will be subsequently used. Utilizando la proyección, puede construir un tipo nuevo creado a partir de cada objeto.By using projection, you can construct a new type that is built from each object. Se puede proyectar una propiedad y realizar una función matemática en ella.You can project a property and perform a mathematical function on it. También puede proyectar el objeto original sin cambiarlo.You can also project the original object without changing it.

Los métodos del operador de consulta estándar que realizan proyecciones se indican en la sección siguiente.The standard query operator methods that perform projection are listed in the following section.

MétodosMethods

Nombre del métodoMethod Name DescripciónDescription Sintaxis de la expresión de consulta de C#C# Query Expression Syntax Más informaciónMore Information
SeleccionarSelect Proyecta valores basados en una función de transformación.Projects values that are based on a transform function. select Enumerable.Select

Queryable.Select
SelectManySelectMany Proyecta secuencias de valores que se basan en una función de transformación y después los convierte en una secuencia.Projects sequences of values that are based on a transform function and then flattens them into one sequence. Use varias cláusulas fromUse multiple from clauses Enumerable.SelectMany

Queryable.SelectMany

Ejemplos de sintaxis de expresiones de consultaQuery Expression Syntax Examples

SeleccionarSelect

En el ejemplo siguiente se usa la cláusula select para proyectar la primera letra de cada cadena de una lista de cadenas.The following example uses the select clause to project the first letter from each string in a list of strings.

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

SelectManySelectMany

En el ejemplo siguiente se usan varias cláusulas from para proyectar cada palabra de todas las cadenas de una lista de cadenas.The following example uses multiple from clauses to project each word from each string in a list of strings.

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 frente a SelectManySelect versus 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.The work of both Select() and SelectMany() is to produce a result value (or values) from source values. Select() genera un valor de resultado para cada valor de origen.Select() produces one result value for every source value. El resultado global, por tanto, es una colección que tiene el mismo número de elementos que la colección de origen.The overall result is therefore a collection that has the same number of elements as the source collection. En cambio, SelectMany() genera un resultado global único que contiene subcolecciones concatenadas procedentes de cada valor de origen.In contrast, SelectMany() produces a single overall result that contains concatenated sub-collections from each source value. 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.The transform function that is passed as an argument to SelectMany() must return an enumerable sequence of values for each source value. Luego, SelectMany() concatena estas secuencias enumerables para crear una secuencia de gran tamaño.These enumerable sequences are then concatenated by SelectMany() to create one large sequence.

Las dos ilustraciones siguientes muestran la diferencia conceptual entre las acciones de estos dos métodos.The following two illustrations show the conceptual difference between the actions of these two methods. En cada caso, se supone que la función de selector (transformación) selecciona la matriz de flores de cada valor de origen.In each case, assume that the selector (transform) function selects the array of flowers from each source value.

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.This illustration depicts how Select() returns a collection that has the same number of elements as the source collection.

Gráfico en el que se muestra la acción 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.This illustration depicts how SelectMany() concatenates the intermediate sequence of arrays into one final result value that contains each value from each intermediate array.

Gráfico en el que se muestra la acción SelectMany().

Ejemplo de códigoCode Example

En el ejemplo siguiente se compara el comportamiento de Select() y SelectMany().The following example compares the behavior of Select() and SelectMany(). El código crea un "ramo" de flores tomando los dos primeros elementos de cada lista de nombres de flores de la colección de origen.The code creates a "bouquet" of flowers by taking the first two items from each list of flower names in the source collection. 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.In this example, the "single value" that the transform function Select<TSource,TResult>(IEnumerable<TSource>, Func<TSource,TResult>) uses is itself a collection of values. Para ello, se requiere el bucle adicional foreach a fin de enumerar cada una de las cadenas de cada subsecuencia.This requires the extra foreach loop in order to enumerate each string in each sub-sequence.

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

Vea tambiénSee also