2010-12-04 56 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維持秩序]的可能重複: //sackoverflow.com/questions/204505/preserving-order-with-linq) – 2010-12-04 22:04:30

+0

同意重複的建議,這個問題應該已經回答。幾乎是該問題的一個具體子問題。不確定是要刪除還是投票結束參考其他問題? – 2010-12-06 17:38:01

回答

3

Distinct方法的文檔沒有說明訂單是否被保留。這可能是因爲它取決於源的底層實現。

您可以使用分組來獲得期望的結果,從各廠家獲得最快的賽車,然後從那個最快的三個:

var topThreeFastestCarManufacturers = 
    GetAllCars() 
    .GroupBy(c => c.Manufacturer) 
    .Select(g => g.OrderByDescending(c => c.TopSpeed).First()) 
    .OrderByDescending(c => c.TopSpeed) 
    .Take(3); 
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; 
     } 
    } 
}