Saltar al contenido

¿Puedo seleccionar varios objetos en una consulta Linq?

Solución:

101 ejemplos de LINQ, a saber, Seleccionar – Tipos anónimos 1

... select new { HomeTeam = fixture.HomeTeam, AwayTeam = fixture.AwayTeam };

Lo siguiente devolverá un IEnumerable :

IEnumerable<Team> drew =
    from fixture in fixtures
    where fixture.Played && (fixture.HomeScore == fixture.AwayScore)
    from team in new[]{fixture.HomeTeam, fixture.AwayTeam}
    select team;

O, con el estilo fluido de LINQ:

IEnumerable<Team> drew =
    fixtures
    .Where(fxtr => fxtr.Played && (fxtr.HomeScore == fxtr.AwayScore))
    .SelectMany(fixture => new[]{fixture.HomeTeam, fixture.AwayTeam});

Aplanamiento y FlatMap

Este requisito a menudo se denomina “aplanamiento”. Es decir, tomando un > y convertirlo en un .

SelectMany ambos mapas (un elemento fijo en una matriz de equipos) y aplanados (una secuencia de matrices de equipos en una secuencia de equipos). Es similar a la función “flatMap” en otros lenguajes como Java y JavaScript.

Es posible separar el mapeo y el aplanamiento:

IEnumerable<Team> drew =
    fixtures
    .Where(fxtr => fxtr.Played && (fxtr.HomeScore == fxtr.AwayScore))
    // map 
    .Select(fixture => new[]{fixture.HomeTeam, fixture.AwayTeam})
    // flatten
    .SelectMany(teams => teams);

Otros enfoques

Bloque de iterador

Se puede lograr lo mismo con un bloque de iterador, pero sospecho que este rara vez es el mejor enfoque:

IEnumerable<Team> Drew(IEnumerable<Fixture> fixtures){
    var draws = 
      fixtures
      .Where(fxtr => fxtr.Played && (fxtr.HomeScore == fxtr.AwayScore));

    foreach(var fixture in draws){
        yield return fixture.HomeTeam;
        yield return fixture.AwayTeam;
    }
}

Unión

La unión también es una opción, pero tiene el potencial de producir resultados diferentes a los anteriores:

  1. El orden de los resultados será diferente. Todos los resultados de Casa se devuelven y luego todos los resultados de Visitante.

  2. Union enumera los dispositivos dos veces, por lo que, dependiendo de cómo se implementen los dispositivos, existe la posibilidad de que los dispositivos se actualicen entre llamadas. Por ejemplo, si se agrega un nuevo partido empatado entre llamadas, entonces el equipo visitante podría ser devuelto pero no el equipo local.

Como describe Mike Powell:

IEnumerable<Team> drew =
    ( from fixture in fixtures
      where fixture.Played && (fixture.HomeScore == fixture.AwayScore)
      select fixture.HomeTeam
    ).Union(
      from fixture in fixtures
      where fixture.Played  && (fixture.HomeScore == fixture.AwayScore)
      select fixture.AwayTeam );

Dependiendo de cómo se obtienen / implementan los accesorios, puede valer la pena considerar ‘almacenar en caché’ los accesorios dibujados para evitar tener que enumerarlos dos veces.

var draws = 
    ( from fixture in fixtures
      where fixture.Played  && (fixture.HomeScore == fixture.AwayScore)
      select fixture
    ).ToList();

IEnumerable<Team> drew =
    (from draw in draws select draw.HomeTeam)
    .Union(from draw in draws select draw.AwayTeam);

O usando el estilo fluido:

var draws = 
    fixtures
    .Where(fxtr => fxtr.Played && (fxtr.HomeScore == fxtr.AwayScore))
    .ToList();

IEnumerable<Team> drew =
    draws.Select(fixture => fixture.HomeTeam)
    .Union(draws.Select(fixture => fixture.AwayTeam));

Modificando la clase de Aparato

Se podría considerar agregar “ParticipatingTeams” a la clase Fixture para obtener:

IEnumerable<Team> drew =
    from fixture in fixtures
    where fixture.Played && (fixture.HomeScore == fixture.AwayScore)
    from team in fixture.ParticipatingTeams
    select team;

pero como @MattDeKrey señala, eso requiere un cambio de contrato.

Muestras de código

Las muestras de código están disponibles en Repl.it

Creo que está buscando el método Union de la siguiente manera:

IEnumerable<Team> drew = (from fixture in fixtures
                     where fixture.Played 
                        && (fixture.HomeScore == fixture.AwayScore)
                     select fixture.HomeTeam)
                     .Union(from fixture in fixtures
                     where fixture.Played 
                        && (fixture.HomeScore == fixture.AwayScore)
                     select fixture.AwayTeam);
¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *