Reputation: 249
I have a list of students which looks like this:
List<Student> students = new List<Student>()
{
new Student(){StudentId = 1, StudentName = "Alex", Grade = "FirstGrade", Marks = 98},
new Student(){StudentId = 1, StudentName = "Alex", Grade = "SecondGrade", Marks = 92},
new Student(){StudentId = 1, StudentName = "Alex", Grade = "ThirdGrade", Marks = 95},
new Student(){StudentId = 2, StudentName = "Karen", Grade = "FirstGrade", Marks = 94},
new Student(){StudentId = 2, StudentName = "Karen", Grade = "SecondGrade", Marks = 95},
new Student(){StudentId = 2, StudentName = "Karen", Grade = "ThirdGrade", Marks = 94},
new Student(){StudentId = 3, StudentName = "Nicole", Grade = "FirstGrade", Marks = 91},
new Student(){StudentId = 3, StudentName = "Nicole", Grade = "SecondGrade", Marks = 99},
new Student(){StudentId = 3, StudentName = "Nicole", Grade = "ThirdGrade", Marks = 97},
};
I want to convert students
list to studentReport
list which looks like this:
{ StudentId = 1, StudentName = "Alex", FirstGrade = 98, SecondGrade = 92, ThirdGrade = 95},
{ StudentId = 2, StudentName = "Karen", FirstGrade = 94, SecondGrade = 95, ThirdGrade = 94},
{ StudentId = 3, StudentName = "Nicole", FirstGrade = 91, SecondGrade = 99, ThirdGrade = 97}
I was able to achieve that using this:
var studentReports = students.GroupBy(student => new { student.StudentId, student.StudentName })
.Select(group => new Report()
{
StudentId = group.Key.StudentId,
StudentName = group.Key.StudentName,
FirstGrade = group.Where(student => student.Grade == "FirstGrade").FirstOrDefault().Marks,
SecondGrade = group.Where(student => student.Grade == "SecondGrade").FirstOrDefault().Marks,
ThirdGrade = group.Where(student => student.Grade == "ThirdGrade").FirstOrDefault().Marks
});
Is there any better way of doing this?
Upvotes: 2
Views: 98
Reputation: 1916
Evaluate this possible refactoring:
students.GroupBy(x => x.StudentId).Select(GetReport());
static func for select:
static Func<IGrouping<int, Student>, Report> GetReport() => group =>
{
var report = new Report
{
StudentId = group.Key,
StudentName = group.First().StudentName,
};
foreach (var student in group)
report.SetGrade(student);
return report;
};
specific report grades "setter":
public class Report
{
public void SetGrade(Student student)
{
switch (student.Grade)
{
case "FirstGrade":
FirstGrade = student.Marks; break;
case "SecondGrade":
SecondGrade= student.Marks; break;
case "ThirdGrade":
ThirdGrade= student.Marks; break;
}
}
[...props...]
}
Upvotes: 1