2010-12-04 6 views
6

Wenn ich ein IOrderedEnumberable<Car> habe ich es sortieren und dann eine vorstehende Abfrage tun ...In LINQ, führen Sie Projektionen von einem IOrderedEnumerable <T> die Reihenfolge beibehalten?

die Reihenfolge, in der Projektion erhalten ist?

Zum Beispiel funktioniert dieses Szenario?

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

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

Ist der Name des top3FastestCarManufacturers Variable die Bedeutung vermitteln, was im Code wirklich passiert ist?

+0

möglich Duplikat [Erhaltung Ordnung mit LINQ] (http: //stackoverflow.com/questions/204505/reserving-order-with-linq) –

+0

Stimmen Sie dem doppelten Vorschlag zu und diese Frage wäre beantwortet worden. Fast eine spezifische Teilfrage. Nicht sicher, ob zu löschen oder zu schließen, mit Bezug auf die andere Frage zu schließen? –

Antwort

3

Die Dokumentation für die Distinct Methode über nichts sagen, ob der Auftrag erhalten bleibt oder nicht. Dies liegt wahrscheinlich daran, dass dies von der zugrunde liegenden Implementierung der Quelle abhängt.

können Sie Gruppierung verwenden Sie das gewünschte Ergebnis zu erhalten, indem das schnellste Auto von jedem Hersteller bekommen, und dann bekommen die drei schnellsten davon:

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

Dies ist eine gute Möglichkeit, wenn Sie nur eine Spalte (Eigenschaft) von der Tabelle (Objekt) benötigen, aber sie wird zusammenbrechen, wenn Sie mehr als eine benötigen - sagen Sie, Sie wollten sowohl die Marke als auch das Modell der Autos von den "Top 3" Herstellern. Nicht wirklich eine Kritik an der Technik, aber es beruht auf der Tatsache, dass Sie nicht die Integrität von Tupeln aufrechterhalten müssen, die zusammenbricht, wenn Sie mehr als eine Eigenschaft von Interesse haben. – tvanfosson

+0

@tvanfosson: Was meinst du? Es gibt drei Autoobjekte mit allen Eigenschaften zurück, keine einzige Eigenschaft. Ironischerweise hat deine eigene Antwort * diese Einschränkung ... – Guffa

+0

Entschuldigung, ich muss nicht genau genug gelesen haben. Ich dachte, du würdest eine Abfrage machen, die in 'select manager, max (topspeed) von ... 'übersetzt wurde. Ich frage mich, wie das SQL dafür aussieht. – tvanfosson

3

Ich vermute, was dich durcheinander bringen wird, ist das Distinct. Dies wird wahrscheinlich die Ergebnisse nach Hersteller umordnen, um die eindeutigen Ergebnisse zu erzeugen. Ich würde wahrscheinlich nur die Liste durchlaufen, bis ich drei verschiedene Hersteller hatte.

Die Auswahl behält die Reihenfolge bei, aber die Bemerkungen zu Distinct geben an, dass sie eine ungeordnete Ergebnismenge zurückgibt und dass sie implementierungsabhängig ist. Natürlich würde ich mich nicht darauf verlassen, dass es die Reihenfolge beibehält und es einfach mit der Iteration macht.

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; 
     } 
    } 
} 
Verwandte Themen