使用LINQ获取一周中每天的平均值

57hvy0tb  于 2023-01-28  发布在  其他
关注(0)|答案(2)|浏览(108)

我是C#新手,这是我第一次使用LINQ查询。我有一个字典Dictionary<(int MeterId, DateTime TimeStamp), float>,数据如下,

<(10411, 12/1/2022 12:30:00 AM), 5700>
<(10411, 13/1/2022 12:30:00 AM), 5200>
<(10412, 12/1/2022 12:30:00 AM), 200>

然后有一种方法可以将它们添加到一个列表中,该列表包含meterId和一周中每一天的平均值。我使用LINQ查询来计算平均值,并将它们添加到列表中。

public static List<AveragedMeter> CalculateAverageValues(Dictionary<(int MeterId, DateTime TimeStamp), float> groupedMeterValues)
        {
            var lstResult = groupedMeterValues
                .GroupBy(m => new { m.Key.MeterId, m.Key.TimeStamp.DayOfWeek })
                .Select(g => new AveragedMeter
                {
                    MeterId = g.Key.MeterId,
                    AverageMondayValue,
                    AverageTuesdayValue,
                    AverageWednesdayValue,
                    AverageThursdayValue,
                    AverageFridayValue,
                    AverageSaturdayValue,
                    AverageSundayValue
                })
                .ToList();

            return lstResult;
        }

我不确定如何得到这些平均值。我的AveragedMeter类如下所示,

class AveragedMeter
    {
        public int MeterId { get; set; }
        public float AverageMondayValue { get; set; }
        public float AverageTuesdayValue { get; set; }
        public float AverageWednesdayValue { get; set; }
        public float AverageThursdayValue { get; set; }
        public float AverageFridayValue { get; set; }
        public float AverageSaturdayValue { get; set; }
        public float AverageSundayValue { get; set; }
    }
mcdcgff0

mcdcgff01#

您可以按DayOfWeek在您的选择中过滤数据,而不是对字典进行分组,如下所示:

static List<AveragedMeter> CalculateAverageValues(Dictionary<(int MeterId, DateTime TimeStamp), float> groupedMeterValues)
{
    var lstResult = groupedMeterValues
        .GroupBy(m => m.Key.MeterId)
        .Select(g => new AveragedMeter
        {
            MeterId = g.Key,
            AverageMondayValue = g.Where(n => n.Key.TimeStamp.DayOfWeek == DayOfWeek.Monday).Average(n => n.Value),
            AverageTuesdayValue = g.Where(n => n.Key.TimeStamp.DayOfWeek == DayOfWeek.Tuesday).Average(n => n.Value),
            AverageWednesdayValue = g.Where(n => n.Key.TimeStamp.DayOfWeek == DayOfWeek.Wednesday).Average(n => n.Value),
            AverageThursdayValue = g.Where(n => n.Key.TimeStamp.DayOfWeek == DayOfWeek.Thursday).Average(n => n.Value),
            AverageFridayValue = g.Where(n => n.Key.TimeStamp.DayOfWeek == DayOfWeek.Friday).Average(n => n.Value),
            AverageSaturdayValue = g.Where(n => n.Key.TimeStamp.DayOfWeek == DayOfWeek.Saturday).Average(n => n.Value),
            AverageSundayValue = g.Where(n => n.Key.TimeStamp.DayOfWeek == DayOfWeek.Sunday).Average(n => n.Value),         
        })
        .ToList();

    return lstResult;
}
bkhjykvo

bkhjykvo2#

这个答案并不是性能最优的,因为它迭代了所有的值7次(不包括GroupBy())。我提出了一个只迭代值两次的解决方案:

static List<AveragedMeter> CalculateAverageValues(
    Dictionary<(int MeterId, DateTime TimeStamp), float> groupedMeterValues)
    => groupedMeterValues
        .GroupBy(g => g.Key.MeterId)
        .Select(g => CalculateAverageDays(
            g.Key,
            g.ToLookup(x => x.Key.TimeStamp.DayOfWeek, x => x.Value)))
        .ToList();

static AveragedMeter CalculateAverageDays(
    int meterId,
    ILookup<DayOfWeek, float> valuesPerDay)
    => new AveragedMeter {
        MeterId = meterId,
        AverageMondayValue = valuesPerDay[DayOfWeek.Monday].DefaultIfEmpty().Average(),
        AverageTuesdayValue = valuesPerDay[DayOfWeek.Tuesday].DefaultIfEmpty().Average(),
        AverageWednesdayValue = valuesPerDay[DayOfWeek.Wednesday].DefaultIfEmpty().Average(),
        AverageThursdayValue = valuesPerDay[DayOfWeek.Thursday].DefaultIfEmpty().Average(),
        AverageFridayValue = valuesPerDay[DayOfWeek.Friday].DefaultIfEmpty().Average(),
        AverageSaturdayValue = valuesPerDay[DayOfWeek.Saturday].DefaultIfEmpty().Average(),
        AverageSundayValue = valuesPerDay[DayOfWeek.Sunday].DefaultIfEmpty().Average()
    };

相关问题