如何按集合对集合进行分组?

时间:2019-10-24 09:43:17

标签: c# linq

我有一个具有实现多对多关系的集合的集合,这是一个示例:

Student : [
    Name,
    Age,
    Teacher : [
        Name,
        Age
    ]
]

我希望首先按老师对学生进行分组,以便可以将老师添加到另一个集合中,然后再添加学生。因此,基本上,我想要上述集合的反面。

Teacher : [
    Name,
    Age,
    Student : [
        new Student {},
        new Student {}
    ]
]

我已经尝试过了:

var teachers = from s in students
               group s by s.Teacher.Name
               into g
               select new { Teacher = g.Key, Students = g.toList()};

但是它只会返回老师的name,而不是整个老师的信息。

3 个答案:

答案 0 :(得分:0)

尝试以下操作:

    class Program
    {
        static void Main(string[] args)
        {
            List<Student> students = new List<Student>();

            var teachers = students.SelectMany(x => x.teachers.Select(y => new { 
                studentName = x.Name,
                studentAge = x.Age,
                teacherName = y.Name,
                teacherAge = y.Age
            }))
            .GroupBy(x => x.teacherName)
            .ToList();
        }
    }
    public class Student
    {

        public string Name { get;set;}
        public int Age { get;set;}
        public List<Teacher> teachers { get;set;}
    }
    public class Teacher
    {
        public string Name { get; set; }
        public int Age { get; set; }
    }

答案 1 :(得分:0)

尝试关注

class Student
    {
        public string Name { get; set; }
        public int Age { get; set; }
        public Teacher Teacher { get; set; }
    }

    class Teacher
    {
        public string Name { get; set; }
        public int Age { get; set; }
    }

分配值:

List<Student> Students = new List<Student>()
{
 new Student {Name = "Ron" , Age = 26, Teacher = new Teacher {Name = "Sam",   Age = 26}},
 new Student {Name = "Jon" , Age = 28 ,Teacher = new Teacher {Name = "Andy" , Age = 56}},
 new Student {Name = "Won" , Age = 28 ,Teacher = new Teacher {Name = "Andy" , Age = 56}},
 new Student {Name = "Tol" , Age = 28 ,Teacher = new Teacher {Name = "Andy" , Age = 56}}
};

山姆老师有一个学生,安迪老师有三个学生。

使用LINQ:

var teachers = Students.GroupBy(x => new { x.Teacher.Name, x.Teacher.Age} )
                      .Select(gr => new {
                          TeacherName = gr.Key.Name,
                          TeacherAge = gr.Key.Age,
                          students = gr.ToList(),
                      });

我们必须按姓名和年龄分组,才能获得老师的姓名和年龄。

答案 2 :(得分:0)

您确定老师的名字是唯一的吗?如果您有两个名称相同的教师,您确定其他所有属性也都相同吗?在这种情况下,您不必按教师姓名分组,但是可以按完整的教师分组。

按老师ID分组会更有效吗?

无论如何,我认为您应该首先弄平“学生与老师”集合,然后按老师的名字分组:

TeachersWithTheirStudents = students
    // Flatten the Student with his Teachers into StudentTeacherCombinations:
    .SelectMany(student => student.Teachers,
        (student, teacher) => new
        {
            Student = student,
            Teacher = teacher,
        })
    // GroupBy Teacher name:
    .GroupBy(studentTeacherCombination => studentTeacherCombination.Teacher.Name,
         (teacherName, studentTeacherCombinationsWithThisTeacherName) => new
         {
             // All studentTeacherCombinations of teachers with TeacherName
             // are expected to be equal, so we can just remember the first one:
             Teacher = studentTeacherCombinationsWithThisTeacherName
                       .Select(studentTeacherCombi=> studentTeacherCombi.Teacher)
                       .FirstOrDefault(), // I'm sure there is at least one
             StudentsOfTeacher = studentTeacherCombinationsWithThisTeacherName
                        .Select(studentTeacherCombi => studentTeacherCombi.Student),
         })
         // Finally put this into a Teacher object:
         .Select(teacherWithHisStudents => new Teacher()
         {
             Id = teacherWithHisStudents.Teacher.Id,
             Name = teacherWithHisStudents.Teacher.Name,
             ... // other Teacher properties

             Students = teacherWithHisStudents.StudentsOfTeacher
                        .Select(student => new Student()
                        {
                            Id = student.Id,
                            Name = student.Name,
                            ... // other Student properties
                        })
                        .ToList(),
    });

         });