【问题标题】:How to get Average of grouped results in Linq query如何在 Linq 查询中获取分组结果的平均值
【发布时间】:2016-11-29 09:37:55
【问题描述】:

我有一个获取前 12 个月评分的 linq 查询:

var ratingsByMonth =
    from month in Enumerable.Range(0, 12)
    let key = new { Year = DateTime.Now.AddMonths(-month).Year, Month = DateTime.Now.AddMonths(-month).Month }
    join groupedRating in ratings on key
            equals new
            {
                groupedRating.RatingDate.Year,
                groupedRating.RatingDate.Month
            } into g
    select new {
        Date = key,
        Rating = g.Select(x=>x.Rating)
    };

ratingsByMonth 从我的数据集中返回以下 JSON:

{Date: {Year: 2016, Month: 11}, Rating: [4]}
{Date: {Year: 2016, Month: 10}, Rating: [5, 5, 4]}
{Date: {Year: 2016, Month: 9}, Rating: []}
{Date: {Year: 2016, Month: 8}, Rating: []}
{Date: {Year: 2016, Month: 7}, Rating: []}
{Date: {Year: 2016, Month: 6}, Rating: []}
{Date: {Year: 2016, Month: 5}, Rating: []}
{Date: {Year: 2016, Month: 4}, Rating: []}
{Date: {Year: 2016, Month: 3}, Rating: []}
{Date: {Year: 2016, Month: 2}, Rating: []}
{Date: {Year: 2016, Month: 1}, Rating: []}
{Date: {Year: 2015, Month: 12}, Rating: []}

但是,我正在尝试将 Rating 字段汇总为平均值。我试过这个:

return Json(new
{
    Average = ratingsByMonth.Average(x=>x.Rating),
    Dates = ratingsByMonth.Select(x => Date)
});

但我在平均 - 行上突出显示以下错误:

不能隐式转换类型 'System.Collections.Generic.IEnumerable' 到 'long?'

我正在寻找的输出是:

{Date: {Year: 2016, Month: 11}, Rating: 4}
{Date: {Year: 2016, Month: 10}, Rating: 3.5}
{Date: {Year: 2016, Month: 9}, Rating: 0}
{Date: {Year: 2016, Month: 8}, Rating: 0}
{Date: {Year: 2016, Month: 7}, Rating: 0}
{Date: {Year: 2016, Month: 6}, Rating: 0}
{Date: {Year: 2016, Month: 5}, Rating: 0}
{Date: {Year: 2016, Month: 4}, Rating: 0}
{Date: {Year: 2016, Month: 3}, Rating: 0}
{Date: {Year: 2016, Month: 2}, Rating: 0}
{Date: {Year: 2016, Month: 1}, Rating: 0}
{Date: {Year: 2015, Month: 12}, Rating: 0}

编辑:

已尝试更改为以下内容:

return Json(new
{
    Average = ratingsByMonth.Select(x => x.Rating).SelectMany(x => x).Average(),
    Dates = ratingsByMonth.Select(x => x.Date.Month)
});

但是,这只是为我提供了整个数据集的单个“平均值”值,而不是每个日期的平均值。

编辑:

这里是示例数据:

RatingID    Rating  RatingDate
5           5   2016-10-09 20:11:29.590
11          0   2016-10-09 20:14:42.503
21          5   2016-10-09 20:24:15.667
60          4   2016-10-28 11:01:21.220
64          4   2016-11-03 16:30:47.657

所以 11 月的平均值应该是 4,10 月应该是 3.5 (5+0+5+4 / 4)

【问题讨论】:

  • json 与您在 linq 中显示的内容不匹配。是日期还是组标准?在给定示例数据的情况下,还显示所需的输出。我认为您可能正在寻找 SelectMany 然后是 Average
  • 谢谢,已更新

标签: c# linq


【解决方案1】:

在原始查询中您可能想要这样做。

//other code removed for brevity
select new {
    Date = key,
    Rating = g.Count() > 0 ? g.Average(x => x.Rating) : 0
};

然后返回结果

return Json(ratingsByMonth);

【讨论】:

  • 已经尝试过了,但是每次我在这一点上运行 Average() 时,我都会得到 Sequence 不包含任何元素。已尝试添加 .Where(x=x.Rating != 0)
  • 好的。我可以看一小部分收视率数据吗
  • 我已更新以显示 ratingsByMonth 的准确输出和所需的输出。请注意,对于 10 月,ratingsByMonth 将忽略 0 个条目之一。
  • 完美!非常感谢。
【解决方案2】:

这里的问题是属性 Rating 本身是一个序列,而不是您可以要求 Average 方法考虑的离散值。

听起来您实际上想要执行以下操作:将所有 Rating 集合扁平化为一个序列,然后对所有结果值取平均值。

类似:

var avg = ratingsByMonth.Select(x => x.Rating).SelectMany(x => x).Average()

这使用 Select 来生成一系列 Rating 数组。 SelectMany 然后将列表展平,之后您可以取平均值。

【讨论】:

  • 感谢您的关注,用结果更新了我的问题,这并不是我想要的。 :-)
猜你喜欢
  • 2021-05-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多