簡體   English   中英

LINQ方法計算有多少學生至少有一個科目的最高成績

[英]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);
    }
}

示例:我們有三個參加者和三個分數:(應該只顯示具有代碼 - B13798Student ,因為具有代碼 - B13799Student在提供的兩個科目中只有一個的值為 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()

你可以

  • 通過按StudentIdmarks進行分組,為每個學生創建一組標記
  • 對於每個這樣的組 ( marksForStudent ),通過按SubjectCodemarksForStudent進行分組,為每個主題創建一組標記
  • 對於每個學生,驗證每個此類組 ( 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替換Studentstring ProgrammeID屬性,並在那里收集所有學生的程序 ID。 這樣,您可以為每個學生定義一次,而不是為他們參加的每個課程定義同一個學生。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM