如何分组和计算逗号分隔字符串中项目的出现次数

use*_*289 3 c# linq

我有一个具有以下属性的Student类

public class Student
{
    public string Name{ get; set; }
    public string Subject { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

假设我们有一个像下面这样的学生名单

var students = new List<Student>();
students.Add(new Student { Name = "John", Subject = "Math"});
students.Add(new Student { Name = "Bob", Subject = "English, Math"});
students.Add(new Student { Name = "Jane", Subject = "Math, History, Art"});
students.Add(new Student { Name = "Jim", Subject = "English"});
Run Code Online (Sandbox Code Playgroud)

我想按主题对学生进行分组并计算主题.

所以输出就是

Math, 3
English, 1
History 1
Art 1
Run Code Online (Sandbox Code Playgroud)

如何使用linq实现结果?

And*_*air 7

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..
Run Code Online (Sandbox Code Playgroud)


pok*_*oke 6

基本上,你想要做的是先获得所有学生的科目,然后收集这些科目.为此,您需要Subject用逗号分割,然后修剪结果(以消除逗号周围的空白).这将为您提供所有科目的列表.

现在您需要做的就是计算每个主题在列表中出现的频率.要做到这一点,你可以使用GroupBy.之后,您将按名称分组所有科目,因此您只需要计算每组中的科目数.

然后,您可以在字典中收集该结果,例如:

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);
}
Run Code Online (Sandbox Code Playgroud)

顺便说一句.这Student.Subject是一个逗号分隔的学生科目字符串似乎有点奇怪.您应该考虑在那里使用列表,以便从头开始分隔值.由于该属性包含多个主题,因此您还应该复制该名称:

public class Student
{
    public string Name { get; set; }
    public List<string> Subjects { get; set; }
}
Run Code Online (Sandbox Code Playgroud)