【问题标题】:In LINQ, do projections off an IOrderedEnumerable<T> preserve the order?在 LINQ 中, IOrderedEnumerable<T> 的投影会保留顺序吗?
【发布时间】:2010-12-04 15:26:59
【问题描述】:

如果我有一个IOrderedEnumberable&lt;Car&gt;,我对其进行排序,然后进行投影查询...

投影中是否保留了顺序?

例如,这种情况是否可行?

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

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

top3FastestCarManufacturers 变量的名称是否传达了代码中实际发生的事情的含义?

【问题讨论】:

  • Preserving order with LINQ 的可能重复项
  • 同意重复的建议,这个问题会得到回答。几乎是那个的一个特定的子问题。不确定是要删除,还是参考其他问题投票结束?

标签: c# .net linq


【解决方案1】:

Distinct 方法的文档没有说明订单是否保留。这可能是因为它取决于源的底层实现。

您可以使用分组来获得所需的结果,方法是从每个制造商那里获得最快的汽车,然后从中获得最快的三个:

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

【讨论】:

  • 如果您只需要表(对象)中的一列(属性),这是一种很好的方法,但如果您需要多个列(属性),它会崩溃——假设您想要两者“前 3 名”制造商的汽车品牌和型号。并不是对该技术的真正批评,但它依赖于这样一个事实,即您不必维护元组的完整性,当您拥有多个感兴趣的属性时,元组的完整性就会崩溃。
  • @tvanfosson:你什么意思?它返回三个具有所有属性的汽车对象,而不是单个属性。具有讽刺意味的是,您自己的答案确实有这个限制......
  • 抱歉,一定没有仔细阅读。我以为你在做一个翻译成select manufacturer, max(topspeed) from ...的查询我想知道它的SQL是什么样子的。
【解决方案2】:

我怀疑会让你感到困惑的是 Distinct。这可能会按制造商重新排序结果以产生不同的结果。我可能会遍历列表,直到找到三个不同的制造商。

选择将保留顺序,但 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;
        }
    }
}

【讨论】:

    猜你喜欢
    • 2013-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-27
    • 1970-01-01
    • 2010-11-29
    • 2011-12-26
    • 1970-01-01
    相关资源
    最近更新 更多