2010-12-04 9 views
6

Si tengo una IOrderedEnumberable<Car>, que ordenarla y luego hacer una consulta proyectando ...En LINQ, ¿las proyecciones de un IOrderedEnumerable <T> conservan el orden?

es el orden conservado en la proyección?

Por ejemplo, ¿funciona esta situación?

IOrderedEnumberable<Car> allCarsOrderedFastestToSlowest = 
      GetAllCars() 
        .OrderByDescending(car=>car.TopSpeed); 

var top3FastestCarManufacturers = 
      allCarsOrderedFastestToSlowest 
        .Select(car=>car.Manufacturer) 
        .Distinct() 
        .Take(3); 

viene el nombre de la variable top3FastestCarManufacturers transmitir el significado de lo que realmente ha sucedido en el código?

+0

posible duplicado de [preservar el orden con LINQ] (http: //stackoverflow.com/questions/204505/preserving-order-with-linq) –

+0

Estoy de acuerdo con la sugerencia duplicada y esta pregunta habría sido respondida. Casi una sub-pregunta específica de eso. ¿No estoy seguro de si eliminar o votar para cerrar con referencia a la otra pregunta? –

Respuesta

3

La documentación para el método Distinct no dice nada acerca de si la orden se conserva o no. Esto es probablemente porque depende de la implementación subyacente de la fuente.

se puede utilizar agrupación para obtener el resultado deseado, por conseguir el coche más rápido de cada fabricante, y luego los tres más rápido de lo siguiente:

var topThreeFastestCarManufacturers = 
    GetAllCars() 
    .GroupBy(c => c.Manufacturer) 
    .Select(g => g.OrderByDescending(c => c.TopSpeed).First()) 
    .OrderByDescending(c => c.TopSpeed) 
    .Take(3); 
+0

Esta es una buena manera de hacerlo si todo lo que necesita es una columna (propiedad) de la tabla (objeto), pero se descompondrá si necesita más de uno, digamos que desea tanto la marca como el modelo de los automóviles. de los "3 principales" fabricantes. No es realmente una crítica de la técnica, pero se basa en el hecho de que no tiene que mantener la integridad de las tuplas, que se descompone cuando tiene más de una propiedad de interés. – tvanfosson

+0

@tvanfosson: ¿Qué quieres decir? Devuelve tres objetos de carro completos con todas las propiedades, no una sola propiedad. Irónicamente, su propia respuesta * tiene * esta limitación ... – Guffa

+0

lo siento, no debe haber leído con suficiente atención. Pensé que estabas haciendo una consulta que se tradujo en 'seleccionar fabricante, max (velocidad máxima) a partir de ...' Me pregunto cómo se verá el SQL. – tvanfosson

3

Sospecho que lo que te va a ensuciar es lo Distintivo. Es probable que esto reordene los resultados por fabricante para producir resultados distintos. Probablemente solo iteraría en la lista hasta que tuviera tres fabricantes distintos.

La selección retendrá el pedido, pero las observaciones en Distinct indican que devuelve un conjunto de resultados desordenados y que depende de la implementación. Para estar seguro, no confiaría en que retenga el pedido y simplemente lo haga usando la iteración.

var top3 = new List<string>(); 
foreach (var manufacturer in allCarsOrderedFastestToSlowest 
           .Select(car=>car.Manufacturer)) 
{ 
    if (!top3.Contains(manufacturer)) 
    { 
     top3.Add(manufacturer); 
     if (top3.Count == 3) 
     { 
      break; 
     } 
    } 
} 
Cuestiones relacionadas