【问题标题】:C# LINQ Group byC# LINQ 分组方式
【发布时间】:2016-05-17 08:36:28
【问题描述】:

我是 C# 新手,正在尝试回答一些 LINQ 问题。我被困在第一个标记为困难...

问:平均出发延误最多的前 10 个始发机场是哪些,包括这些延误的数值? (提示:使用 group by)?

我有一个名为“Flights”的列表,其中包含超过 20000 个“FlightInfo”的对象。

FlightInfo 类的属性是: string Carrier, string Origin, string Destination, int DepartureDelay, int ArrivalDelay, int Cancelled, int Distance.

我知道我应该按 FlightInfo.Origin 对 FlightInfo 进行分组,然后按 FlightInfo.DepartureDelay 对每个组进行平均,然后显示平均延迟最高的 10 个,但除了分组之外,我完全不知道如何进一步进行。

提前感谢您的帮助!


这是我之前能够回答的问题之一的示例:

问:航班的加权到达延迟是它的到达延迟除以距离。从马萨诸塞州波士顿起飞的加权到达延迟最大的航班是什么?

答:

var weighted = (from FlightInfo in Flights
               where FlightInfo.Origin == "Boston MA"
               orderby (FlightInfo.ArrivalDelay / FlightInfo.Distance) descending
               select FlightInfo).Take(1);

【问题讨论】:

  • 已回答问题的旁注:Take 返回 IEnumerable<T> 如果您想要 T 实例,请使用 FirstFirstOrDefault
  • 是的,我看到当我使用First 时,我可以在不使用foreach 循环的情况下访问属性。谢谢,我之前不明白为什么我不能Console.WriteLine(weighted.Origin)

标签: c# linq average


【解决方案1】:
var topTen = flights.
            GroupBy(g => g.Origin).
            Select(g => new { Origin = g.Key, AvgDelay = g.ToList().Average(d => d.DepartureDelay) }).
            OrderByDescending(o => o.AvgDelay).
            Take(10);

【讨论】:

  • 谢谢,这是我问题的完整解决方案。现在由于我是新手,我仍然无法掌握语法,看来我正在向前跳跃。我有很多东西要学...
  • 首先按一个键分组。 Linq 制作了一个字典,其中键是您分组的键,值是这些对象的列表(与 SQL 有点不同)。之后,我们为这些组中的每一个进行选择,在其中我们创建一个具有属性 Origin 和 AvgDelay 的新匿名对象。平均延迟是该特定键的列表中所有对象的平均值。之后就很容易了 - 按 AvgDelay 订购并获得前 10 个。
  • 非常感谢。我理解逻辑,但无论我如何尝试,我都无法向 Select 添加另一个属性。假设我也想展示 Carrier。 Select(g => new { Origin = g.Key, AvgDelay = g.ToList().Average(d => d.DepartureDelay), Company = g.ToList().????(p => p.Carrier)???? })
【解决方案2】:
var result = flights
    .GroupBy(f => f.Origin)
    .OrderByDescending(g => g.Average(f => f.DepartureDelay))        
    .Take(10)
    .Select(g => new
    {
        AirportName = g.Key,
        Flights = g.ToList()
    });

最后一个.Select 参数取决于你想要什么。

【讨论】:

  • 感谢您的回答。它给出了正确但不完整的答案。由于我是新手,我无法自己添加其他属性(出发延迟)。
【解决方案3】:

你可以这样做。

var top10 = Flights.GroupBy(g=>g.Origin) // groupby origin 
                  .OrderByDescending(x=> x.Sum(f=> f.ArrivalDelay / f.Distance))  // Get the weighted delay for each fight and use for ordering.
                  .Select(x=>x.Key)  //Airport or Origin (Modify with what you want)
                  .Take(10)
                  .ToList() ;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-09-07
    • 2013-01-06
    • 2012-07-16
    • 2010-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多