Linq排序,按组排列和排序?

我有一个像这样的对象:

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

我想创建以下查询:按学生姓名分组学习成绩,按年级排列每个学生组,按每个组的最高成绩排序组。

所以它看起来像这样:

A 100
A 80
B 80
B 50
B 40
C 70
C 30

我创建了以下查询:

StudentsGrades.GroupBy(student => student.Name)
    .OrderBy(studentGradesGroup => studentGradesGroup.Max(student => student.Grade));

但是,这将返回IEnumerable IGrouping ,并且我无法对列表进行排序,除非我在另一个foreach查询中执行此操作,并使用AddRange将结果添加到其他列表中。

有没有更好的方法来做到这一点?


当然:

var query = grades.GroupBy(student => student.Name)
                  .Select(group => 
                        new { Name = group.Key,
                              Students = group.OrderByDescending(x => x.Grade) })
                  .OrderBy(group => group.Students.First().Grade);

请注意,您可以在订购后仅考虑每个组的第一年级,因为您已经知道第一次入学的成绩是最高的。

然后你可以显示它们:

foreach (var group in query)
{
    Console.WriteLine("Group: {0}", group.Name);
    foreach (var student in group.Students)
    {
        Console.WriteLine("  {0}", student.Grade);
    }
}

我想你想要一个额外的投影,将每个组映射到组的排序版本:

.Select(group => group.OrderByDescending(student => student.Grade))

这也看起来像你可能希望在此之后再进行一次扁平化操作,这会给你一连串的学生,而不是一连串的小组:

.SelectMany(group => group)

您始终可以将两者都折叠为一个SelectMany调用,它可以进行投影并拼合在一起。


编辑:正如Jon Skeet指出的那样,总体查询存在一定的低效率; 从排序每个组获得的信息并未用于组自身的排序。 通过将每个组的排序移动到组本身的排序之前, Max查询可以躲避到更简单的First查询中。


没有投影的方式:

StudentsGrades.OrderBy(student => student.Name).
ThenBy(student => student.Grade);
链接地址: http://www.djcxy.com/p/34271.html

上一篇: Linq order by, group by and order by each group?

下一篇: ORDER BY & LIMIT