2010-12-04 9 views
6

私はIOrderedEnumberable<Car>を持っている場合、私はそれを並べ替え、投影クエリを行う...LINQでは、IOrderedEnumerable <T>から順番を維持して投影を行いますか?

投影で保存された順序ですか?

たとえば、このシナリオは機能しますか?

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

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

top3FastestCarManufacturers変数の名前は、実際にコード内で起こったことの意味を伝えますか?

+0

(HTTP [LINQとの順序を保存]が重複する可能性: //stackoverflow.com/questions/204505/preserving-order-with-linq) –

+0

重複した提案に同意し、この質問に回答していたはずです。ほぼその特定のサブ質問。削除するか、他の質問を参照して閉じるに投票するかはわかりませんか? –

答えて

3

Distinctメソッドのドキュメントには、注文が保存されているかどうかについては何も記載されていません。これはおそらく、ソースの基礎となる実装に依存しているためです。

あなたは、各メーカーから最速の車を取得することにより、望ましい結果を得るために、グループ化を使用することができ、そしてそのから3最速を得る:

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

これは、必要なものがテーブル(オブジェクト)からの1つの列(プロパティ)であれば、それを行う良い方法ですが、複数のものが必要な場合は分解します。たとえば、自動車の製造元とモデル「トップ3」メーカーからこの技術の批判ではありませんが、関心のあるプロパティが2つ以上あるときに分解するタプルの完全性を維持する必要はないという事実に依存しています。 – tvanfosson

+0

@tvanfosson:どういう意味ですか? 1つのプロパティではなく、すべてのプロパティを含む3つのカーオブジェクトを返します。皮肉なことに、あなた自身の答え*はこの制限を持っています... – Guffa

+0

申し訳ありませんが、十分に注意深く読んではいけません。私はあなたが 'select manufacturer、max(topspeed)from ... 'に翻訳されたクエリを実行していると思っていました。 – tvanfosson

3

私はあなたを台無しにしようとしていると思われるのはDistinctです。これにより、結果が明確になるように製造元によって結果が並べ替えられます。私は3つの別個の製造業者があるまでリストを反復するだけだろう。

選択項目には順序が保持されますが、Distinctの注釈は順序付けられていない結果セットを返し、実装に依存することを示します。確かに、私はそれを頼りにして順序を保持せず、単に反復を使用してそれを行います。

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; 
     } 
    } 
} 
関連する問題