[英]LINQ method to count how many students have at least one greatest grade in subject
我们有学生名单和成绩。 学生有ID, Surname, Name, ProgrammeID
,而成绩类: StudentID, SubjectCode, Date and Value
。
主要思想是找到在他参加的所有科目中至少有一个最高成绩( Grade class -> Value >= 10
)的所有学生。
我应该提到,所有这些信息(学生和年级)都存储在单独的列表中。
学生和年级班级如下所示:
class Student
{
public string ID { get; set; }
public string Surname { get; set; }
public string Name { get; set; }
public string ProgrammeID { get; set; }
public Student(string id, string surname, string name, string programmeID)
{
this.ID = id;
this.Surname = surname;
this.Name = name;
this.ProgrammeID = programmeID;
}
public override string ToString()
{
return String.Join("; ", ID, Surname, Name, ProgrammeID);
}
}
class Grade
{
public string StudentID { get; set; }
public string SubjectCode { get; set; }
public DateTime Date { get; set; }
public int Value { get; set; }
public Grade(string studentID, string subjectCode, DateTime date, int value)
{
this.StudentID = studentID;
this.SubjectCode = subjectCode;
this.Date = date;
this.Value = value;
}
public override string ToString()
{
return String.Join("; ", StudentID, SubjectCode, Date, Value);
}
}
示例:我们有三个参加者和三个分数:(应该只显示具有代码 - B13798
的Student
,因为具有代码 - B13799
的Student
在提供的两个科目中只有一个的值为 10)
atendees.Add(new Student("B13799", "Surname0", "Name0", "P175B123"));
atendees.Add(new Student("B13799", "Surname0", "Name0", "P175B122"));
atendees.Add(new Student("B13798", "Surname1", "Name1", "P175B123"));
marks.Add(new Grade("B13799", "P175B123", DateTime.Parse("2021-01-02 12:45:36"), 10));
marks.Add(new Grade("B13799", "P175B122", DateTime.Parse("2021-01-02 12:45:36"), 9));
marks.Add(new Grade("B13798", "P175B123", DateTime.Parse("2021-01-02 12:45:36"), 10));
尝试这个
首先对分数进行分组,找出每个学生和科目的最高分
var group1 = (from r in marks group r by new { r.StudentID, r.SubjectCode } into results
select new { results.Key.StudentID, results.Key.SubjectCode, max = results.Max(x => x.Value)});
然后按学生对这些结果进行分组
var group2 = (from r in group1 group r by r.StudentID into results select results);
最后只选择那些每门科目得 10 分的学生
var list = (from r in group2 where r.All(a=>a.max == 10) select r.Key).ToList()
你可以
StudentId
对marks
进行分组,为每个学生创建一组标记marksForStudent
),通过按SubjectCode
对marksForStudent
进行分组,为每个主题创建一组标记marksForSubject
) 是否包含至少一个通过您给定要求的分数StudentId
它可以这样实现:
List<Student> attendees;
List<Grade> marks;
// Populate lists
var threshold = 10;
var filteredAttendeeIds = marks
.GroupBy(mark => mark.StudentID)
.Where(marksForStudent => marksForStudent
.GroupBy(mark => mark.SubjectCode)
.All(marksForSubject => marksForSubject
.Any(mark => mark.Value >= threshold)))
.Select(marksForStudent => marksForStudent.Key);
然后可以通过学生列表与过滤后的学生 ID 相交来找到学生:
var filteredAttendees = attendees
.IntersectBy(filteredAttendeeIds, attendee => attendee.ID);
示例小提琴在这里。
注意:此实现假定对于attendees
中的每个Student.ProgrammeID
,实际上在marks
中存在一个现有Grade
对象。
边注:
我建议用IEnumerable<string> ProgrammeIds
替换Student
的string ProgrammeID
属性,并在那里收集所有学生的程序 ID。 这样,您可以为每个学生定义一次,而不是为他们参加的每个课程定义同一个学生。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.