【问题标题】:Getting average value of groups with LINQ使用 LINQ 获取组的平均值
【发布时间】:2015-02-10 08:02:43
【问题描述】:

我正在尝试根据列表中每个项目具有的特定值将我的列表分成不同的组,然后在这些组中找到另一个值的平均值。

为了更好地说,我有一个学生列表:

List<Student> students = new List<Student> {
    new Student { Name="Bob", Level=Level.Sophomore, GPA=3.2f },
    new Student { Name="Cathy", Level=Level.Freshman, GPA=3.6f },
    new Student { Name="James", Level=Level.Senior, GPA=3.8f },
    new Student { Name="Jessica", Level=Level.Senior, GPA=3.7f },
    new Student { Name="Derek", Level=Level.Junior, GPA=2.8f },
    new Student { Name="Sam", Level=Level.Junior, GPA=3.1f }
};

我想按他们的班级级别对他们进行分组,因此他们将被分组为新生、大二、大三和大四。然后我希望能够获得这些组的平均 GPA。

因此,这些学生的可能结果集是:

Senior: 3.7
Junior: 2.9
Sophomore: 3.2
Freshman : 3.6

不过,我不太确定如何获得这个结果。我尝试过students.GroupBy(x =&gt; x.Level).Average(); 之类的东西,但它不起作用。

对此的任何想法将不胜感激。谢谢!

【问题讨论】:

标签: c# linq


【解决方案1】:

你必须使用一个额外的Select,所以你正在寻找这样的东西:

var result = students.GroupBy(s => s.Level)
                     .Select(g => new {Level=g.Key, Avg=g.Average(s => s.GPA)});

Select(g =&gt; new {...}) 为每个组创建一个新的匿名类型的实例。

该类型有两个属性:

  • Level,这是组的Key 属性
  • Avg,这是该组的平均GPA

只是“想象”有这种类型在使用(或多或少):

class GroupAverage
{
    public Level Level { get; set; }
    public float Avg { get; set; }
}

var result = students.GroupBy(s => s.Level)
                     .Select(g => new GroupAverage { Level=g.Key, Avg=g.Average(s => s.GPA) } );

但它根本没有名字。


result 现在是:

如果需要,请随意对值进行四舍五入。


要获得平均值最高的Level,只需使用

var highest = result.OrderByDescending(a => a.Avg).First().Level;

(请注意,如果students 中没有项目,这将崩溃)

【讨论】:

  • 你能解释一下这个查询在做什么吗?我不太了解新的 {Level=g.Key, Avg=g.Average(s=>s.GPA)}。
  • 他正在从他之前的组中选择一个匿名对象,具有 2 个属性: 1 分组的键,即级别。第二个属性是对分组的聚合,在这种情况下,他取该分组中所有学生 GPA 的平均值。
  • 按Level分组,然后选择一个新的匿名对象,包含两个值,键值(由group()函数生成)和GPA的平均值。
  • 哦,好的。谢谢!如果我这样选择,我还能选择 GPA 最高的组吗?
  • @user3113376 - 有足够的时间和金钱,您可以做任何事情,包括按 GPA 降序排序并获取 1 项(或第一项)。我建议您下载linqpad.net 并查看 LINQPad 附带的出色示例代码。它真的会帮助你理解。
【解决方案2】:

看看这个:

students.GroupBy(s => s.Level, s => s.GPA, 
                (level, scores) => new { Level = level, Avg = scores.Average() }

【讨论】:

    猜你喜欢
    • 2011-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-26
    • 1970-01-01
    相关资源
    最近更新 更多