students.SelectMany(arg => arg.Subject.Split(new []{','})) // split the Subject-property on commas
        .Select(arg => arg.Trim()) // get rid of the whitespaces after commas
        .GroupBy(arg => arg) // you can inject an equality comparer here, to achieve case insenstive grouping
        .Select(arg => new
                         Subject = arg.Key,
                         Count = arg.Count()
                       }); // TODO output these objects to your console..


Basically, what you want to do is first get the subjects of all students, and just collect those. To do this, you need to split the Subject by the comma, and then trim the results (to get rid of whitespace around the comma). This gives you a list of all subjects.

Now all you need to do is count how often each subject occurs in the list. To do this, you can use just GroupBy. Afterwards, you have all subjects grouped by the name, so you only need to count how many there are in each group.

You can then collect that result for example in a dictionary like this:

IDictionary<string, int> subjectCount = students
    .SelectMany(s => s.Subject.Split(','))
    .Select(s => s.Trim())
    .GroupBy(s => s)
    .ToDictionary(grp => grp.Key, grp => grp.Count());

foreach (var count in subjectCount)
    Console.WriteLine("{0}: {1}", count.Key, count.Value);

Btw. it seems a bit weird that Student.Subject is a comma-separated string of the student’s subjects. You should consider using a list there, so that you have separated values from the beginning. And since the property contains multiple subjects, you should pluralize the name too:

public class Student
    public string Name { get; set; }
    public List<string> Subjects { get; set; }

Related Articles