繁体   English   中英

如何使用LINQ计算列表中每个项目的平均值?

[英]how to calculate average for each item in a list with LINQ?

如何计算每个学生的平均分? 我这样做了......但平均值对我不起作用,我怎么做? 使用 JoinGroup 和 GroupBy ?,我等着看解决方案,谢谢。

var listadoA = alumnos.Join(examenes, 
                        a => a._id,
                        e => e._alumnoId,
                        (a, e) => new
                        {
                            NombreAlumno = a._nombre,
                            Examenes = examenes,
                            Notas = e._nota,
                        }).Where(p => p.Examenes.Count() >= 1).OrderBy(p => p.NombreAlumno).ToList();
        foreach (var obj in listadoA){
            var promedio = obj.Average(p => p.Nota);
            Console.Write($"\nAlumno = {obj.NombreAlumno}, Promedio ={promedio}");
        }   


class Examen{
    public double _nota{get;set;}
    public int _alumnoId {get;set;}
    public int cursoId{get;set;}


    public Examen(int id, double nota, int idMateria){
        this._alumnoId = id;
        this.cursoId = idMateria;
        this._nota = nota;
    }

    public override string ToString(){
        return ($"Alumno = {this._alumnoId}, Nota = {this._nota}, Curso = {this.cursoId}");
    }
    public static List<Examen> GetLista(){
        return new List<Examen>(){
            new Examen(2,5,1),
            new Examen(4,7,5),
            new Examen(4,9,3),
            new Examen(3,10,4),
            new Examen(7,5,3),
            new Examen(2,8,4),
            new Examen(6,9,5),
            new Examen(9,7,1),
            new Examen(6,5,4),
            new Examen(9,1,4),
            new Examen(7,9,5),
        };
    }
}

我的测试时间有点短,但我认为它应该通过一些小的调整来工作。 如果我有任何错别字,请告诉我:

var listadoA = alumnos.GroupJoin(examenes, 
                    a => a._id,
                    e => e._alumnoId,
                    (a, eGroup) => new
                    {
                        Alumno = a,
                        Examenes = eGroup
                        
                    }).Where(p => p.Examenes.Count() >= 1).OrderBy(p => p.Alumno._nombre).ToList();
foreach (var obj in listadoA){
        var promedio = obj.Examenes.Average(e => e._nota);

我很好奇为什么您的以下划线开头的字段可以公开访问; 这是私有字段的命名约定.. 应该真正为它们提供公共属性。 另外,我假设“nota”是考试成绩。

编辑

答案最初是在对所涉及的类进行精确处理之前发布的。 我仍然保留英文命名,因为它可能对更广泛的受众更清晰。 这也有助于澄清我对@Caius Jard 相关评论的回答。

使用 Linq 对象:(不使用实体框架)

与使用 join 相比,此代码执行以下权衡。 它的性能可能较差,但更简单(您甚至不必了解联接是什么)。

AveragesByStudents = Students
    .Select(s => new 
    {
        StudentName = s.Name,
        Notes = Exams
            .Where(e => e.StudentId == s.Id)
            .Select(e => e.Note)
            .ToList()
    })
    .Select(s => new 
    {
        s.StudentName,
        Average = s.Notes.Any() ? s.Notes.Average() : null
    });
;

在此示例中,您可以获得所有学生,即使他们没有笔记(在这种情况下,他们的平均值为空)。 您可以在一个选择中完成它,但它不会更具可读性。

在以下示例中,您仅获取有笔记的学生,因此他们的平均值不能为空。

AveragesByStudents = Students
    .Select(s => new 
    {
        StudentName = s.Name,
        Notes = Exams
            .Where(e => e.StudentId == s.Id)
            .Select(e => e.Note)
    })
    .Where(s => s.Notes.Any())
    .Select(s => new 
    {
        s.StudentName,
        Average = Notes.Average()
    });
;

如果要实现,请在查询末尾添加 ToList()。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM