2010-12-04 58 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; 
     } 
    } 
}