Home > Mobile >  groupby in dictionary in C#
groupby in dictionary in C#

Time:01-31

var dict = new Dictionary<ClassA,int>();

I should add the Name and Seat number into the dict but I have to take it from separate classes, eg

dict.Add(student.name)
dict.Add(class.studentlist.score)

I want it to get an output of

Student   Score
Amy       78
Amy       89
Amy       45
Ben       34
.
.
.

as well as one that shows the total score if the student's name repeats more than once

Student   Score
Amy       (total score)
Ben       (total score)

I'm not sure how to go about doing this, or if it is even possible? The name and score comes from different classes so I'm a bit confused.

CodePudding user response:

You cannot have a dictionary with multiple Name keys, name should be unigue. So try to create a list

var students = new List<Student>();

    students.Add(new Student { Name = "Amy", Score = 78 });
    students.Add(new Student { Name = "Ben", Score = 34 });
    students.Add(new Student { Name = "Amy", Score = 89 });
    students.Add(new Student { Name = "Amy", Score = 45 });

List<string,int> scores = students.GroupBy(s => s.Name)
    .Select(i => new Student { Name = i.Key, Score = i.Sum(x => x.Score) }).ToList();

public class Student
{
    public string Name { get; set; }
    public int Score { get; set; }
}

UPDATE

@Cleptus suggested to use a Dictionary<string, List> where string is a name, and list is to keep the score. It is a very interesting idea, but I like more a list, since it is more like an relational db and linq is ideal for list collections. I feel Dictionaries as too hierarchical , and the always need an extra step or code to get some information.

but dictionary could be used to keep the result information

 Dictionary<string, int> result = students.GroupBy(s => s.Name)
.ToDictionary( i => i.Key, i=> i.Sum(x => x.Score));
  
 var amyResult=result["Amy"];
  

CodePudding user response:

Assuming your class student is:

public class Student
{
    public string Name { get; set; }
}

You could use a Dictionary whose key would be a Student and whose content would be a list/array of scores.

List<Student, List<int>> results = new List<Student, List<int>>();
results.Add(new Student() { Name = "Amy"}, new List<int>() { 78, 89, 45 });
results.Add(new Student() { Name = "Ben"}, new List<int>() { 61 });

And to show the data, you just need to iterate the keys and show the data however you need (either aggregated or individually).

using System.Linq;
....

foreach (Student currentStudent in results.Keys) {
    List<int> studentResults = results[currentStudent];
    
    // This would show your first needed output (individual scores)
    foreach(int result in studentResults) Console.WriteLine(currentStudent.Name   ": "   result.ToString());

    // This would show your second needed output (total scores)
    Console.WriteLine(currentStudent.Name   ": "   studentResults.Sum().ToString());
}

The second one takes advantage of IEnumerable.Sum()

  •  Tags:  
  • Related