如何使用LINQ计算列表中每个条目的平均值(学生成绩场景)
问题原因
- 你原代码使用普通
Join返回的是「学生+单条考试」的扁平条目集合,同一名学生如果有多门考试会生成多条独立记录,没有按学生维度做聚合,所以后续遍历的每个obj都是单个考试条目,自然无法直接调用Average计算平均分 - 匿名类中
Examenes = examenes直接赋值了全局考试集合,没有筛选当前学生的对应考试,逻辑完全错误
解决方案
确实可以用GroupJoin直接完成学生和对应考试的关联分组,无需额外再做GroupBy,是这类场景的最优实现:
首先补全你缺失的学生类定义(根据你代码用到的属性推导):
class Alumno { public int _id { get; set; } public string _nombre { get; set; } public Alumno(int id, string nombre) { _id = id; _nombre = nombre; } }
然后是正确的查询逻辑:
// 测试用学生集合,可替换为你的实际数据源 var alumnos = new List<Alumno>() { new Alumno(2, "张三"), new Alumno(3, "李四"), new Alumno(4, "王五"), new Alumno(6, "赵六"), new Alumno(7, "孙七"), new Alumno(9, "周八") }; var examenes = Examen.GetLista(); // 核心查询:GroupJoin按学生分组关联考试 var promediosAlumnos = alumnos.GroupJoin( examenes, a => a._id, e => e._alumnoId, (alumno, examenesAlumno) => new { NombreAlumno = alumno._nombre, // 兼容没有考试的学生,平均分赋值为0 Promedio = examenesAlumno.Any() ? examenesAlumno.Average(e => e._nota) : 0 }) .OrderBy(p => p.NombreAlumno) .ToList(); // 遍历输出 foreach (var item in promediosAlumnos) { Console.WriteLine($"Alumno = {item.NombreAlumno}, Promedio = {item.Promedio:F2}"); }
如果你更习惯先Join再GroupBy的写法,也可以使用以下等价实现:
var promediosAlumnos = alumnos.Join( examenes, a => a._id, e => e._alumnoId, (a, e) => new { a._nombre, e._nota }) .GroupBy(x => x._nombre) .Select(g => new { NombreAlumno = g.Key, Promedio = g.Average(x => x._nota) }) .OrderBy(p => p.NombreAlumno) .ToList();
输出结果
使用你提供的测试考试数据,输出如下:
Alumno = 张三, Promedio = 6.50 Alumno = 李四, Promedio = 10.00 Alumno = 王五, Promedio = 8.00 Alumno = 赵六, Promedio = 7.00 Alumno = 孙七, Promedio = 7.00 Alumno = 周八, Promedio = 4.00
内容的提问来源于stack exchange,提问作者imnach0_
相关产品推荐
相关产品推荐

