【问题标题】:Show average per hour in a timespan using LINQ使用 LINQ 显示时间跨度内每小时的平均值
【发布时间】:2016-08-17 13:37:25
【问题描述】:

我有一个Part 列表,其中包含一个DateTime 值,表示它们何时注册到我的Database

我想显示每小时白班登记的人数和每晚登记的人数。

我试图将我的总体平均逻辑基于这两个值

@{

var shiftChangeTime = new TimeSpan(16, 0, 0);
<table>
    <tr>
        @*This is my general average*@
        <td>Number of part/hour</td>
        @{
            var avg = Model.GroupBy(x => ((DateTime)x.ScanTime).TimeOfDay.Hours)
                        .Average(x => x.Count());
            <td>@(Math.Round(avg, 2))</td>
        }
    </tr>
    <tr>
        @*This is my day average*@
        <td>Number of part/hour</td>
        @{
            var avgDay = Model.GroupBy(x => ((DateTime)x.ScanTime).TimeOfDay < shiftChangeTime, y => ((DateTime)y.ScanTime).TimeOfDay.Hours)
                        .Average(x => x.Count());
            <td>@(Math.Round(avgDay, 2))</td>
        }
    </tr>
    <tr>
        @*This is my night average*@
        <td>Number of part/hour for night shift</td>
        @{
            var avgNight = Model.GroupBy(x => ((DateTime)x.ScanTime).TimeOfDay > shiftChangeTime, y => ((DateTime)y.ScanTime).TimeOfDay.Hours)
                        .Average(x => x.Count());
            <td>@(Math.Round(avgNight, 2))</td>
        }
    </tr>
</table>
}

我目前坚持以小时为单位区分日班/夜班的逻辑。

现在它把我的总数一分为二。

知道如何进行吗?

【问题讨论】:

    标签: c# linq razor average


    【解决方案1】:

    您上面的代码的问题是,在 GroupBy 的日/夜班之后,您还需要按 Hour 分组,以便进行每小时平均。

    这会为您提供白天/夜班期间一小时内的平均零件数:

    List<Part> Model = new List<Part>
    {
        new Part{ ScanTime = new DateTime(2016,1,1,1,0,0) },
        new Part{ ScanTime = new DateTime(2016,1,1,4,0,0) },
        new Part{ ScanTime = new DateTime(2016,1,1,4,0,0) },
        new Part{ ScanTime = new DateTime(2016,1,1,4,0,0) },
        new Part{ ScanTime = new DateTime(2016,1,1,4,0,0) },
        new Part{ ScanTime = new DateTime(2016,1,1,7,0,0) },
        new Part{ ScanTime = new DateTime(2016,1,1,12, 0,0) },
        new Part{ ScanTime = new DateTime(2016,1,1,17,0,0) },
        new Part{ ScanTime = new DateTime(2016,1,1,19,0,0) },
        new Part{ ScanTime = new DateTime(2016,1,1,23,0,0) },
    };
    
    var shiftChangeTime = new TimeSpan(12, 0, 0);
    
    var result = Model.GroupBy(x => x.ScanTime.TimeOfDay < shiftChangeTime ? "Day" : "Night")
         .Select(g => new
         {
             Shift = g.Key,
             Average = g.GroupBy(item => item.ScanTime.Hour, 
                                 (key, group) => new { Hour = key, Amount = group.Count() })
                        .Average(y => y.Amount)
         }).ToList();
    

    如果您不想要 2 个 GroupBy,另一种选择是首先使用 Where 仅保留特定班次的记录,然后再保留其余部分:

    var dayAverage = Model.Where(x => x.ScanTime.TimeOfDay < shiftChangeTime)
                          .GroupBy(item => item.ScanTime.Hour, 
                                   (key, group) => new { Hour = key, Amount = group.Count() })
                          .Average(y => y.Amount);
    

    【讨论】:

    • 如果我正确获取了您的代码result 应该包含 2 个值,一个是白班平均值,另一个是夜班平均值?我通过result["day"] / result["night"] 访问它们,对吗?
    • @Chax - 您必须像 result[0] 一样访问它。如果你想以你写的方式访问,那么而不是ToListToDictionary
    • 太棒了!谢谢。我会立即尝试并确认是否可行
    • 它就像一个魅力(经过几次调整以适应我的情况)
    • @Chax - 请考虑投票 :) 如果它解决了您的问题,请接受已解决 :)
    猜你喜欢
    • 2011-03-06
    • 1970-01-01
    • 2015-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-17
    • 2021-08-22
    • 2015-04-30
    相关资源
    最近更新 更多