Ich habe ein Objekt, das ungefähr so aussieht:
public class Student
{
public string Name { get; set; }
public int Grade { get; set; }
}
Ich möchte die folgende Abfrage erstellen: Gruppieren Sie die Noten nach Schülernamen, ordnen Sie jede Schülergruppe nach Noten und ordnen Sie die Gruppen nach der Höchstnote in jeder Gruppe.
So wird es aussehen:
A 100
A 80
B 80
B 50
B 40
C 70
C 30
Ich habe die folgende Abfrage erstellt:
StudentsGrades.GroupBy(student => student.Name)
.OrderBy(studentGradesGroup => studentGradesGroup.Max(student => student.Grade));
Aber das kehrt zurück IEnumerable
IGrouping
, und ich habe keine Möglichkeit, die Liste darin zu sortieren, es sei denn, ich mache das in einer anderen foreach
Abfrage und füge die Ergebnisse mit einer anderen Liste hinzu AddRange
.
Gibt es einen schöneren Weg, das zu tun?
quelle
So geht's ohne Projektion:
quelle
Ich denke, Sie möchten eine zusätzliche Projektion, die jede Gruppe einer sortierten Version der Gruppe zuordnet:
.Select(group => group.OrderByDescending(student => student.Grade))
Es scheint auch , wie Sie vielleicht danach eine weitere Abflachung Operation wollen , die Sie anstelle einer Folge von Gruppen eine Folge von Studenten geben:
.SelectMany(group => group)
Sie können beide jederzeit zu einem einzigen
SelectMany
Aufruf zusammenfassen, der die Projektion und das Abflachen zusammen ausführt.EDIT: Wie Jon Skeet betont, gibt es bestimmte Ineffizienzen in der Gesamtabfrage; Die Informationen, die beim Sortieren jeder Gruppe gewonnen werden, werden nicht für die Reihenfolge der Gruppen selbst verwendet. Durch Verschieben der Sortierung jeder Gruppe vor der Reihenfolge der Gruppen selbst kann die
Max
Abfrage in eine einfachereFirst
Abfrage ausgewichen werden.quelle
Versuche dies...
public class Student { public int Grade { get; set; } public string Name { get; set; } public override string ToString() { return string.Format("Name{0} : Grade{1}", Name, Grade); } } class Program { static void Main(string[] args) { List<Student> listStudents = new List<Student>(); listStudents.Add(new Student() { Grade = 10, Name = "Pedro" }); listStudents.Add(new Student() { Grade = 10, Name = "Luana" }); listStudents.Add(new Student() { Grade = 10, Name = "Maria" }); listStudents.Add(new Student() { Grade = 11, Name = "Mario" }); listStudents.Add(new Student() { Grade = 15, Name = "Mario" }); listStudents.Add(new Student() { Grade = 10, Name = "Bruno" }); listStudents.Add(new Student() { Grade = 10, Name = "Luana" }); listStudents.Add(new Student() { Grade = 11, Name = "Luana" }); listStudents.Add(new Student() { Grade = 22, Name = "Maria" }); listStudents.Add(new Student() { Grade = 55, Name = "Bruno" }); listStudents.Add(new Student() { Grade = 77, Name = "Maria" }); listStudents.Add(new Student() { Grade = 66, Name = "Maria" }); listStudents.Add(new Student() { Grade = 88, Name = "Bruno" }); listStudents.Add(new Student() { Grade = 42, Name = "Pedro" }); listStudents.Add(new Student() { Grade = 33, Name = "Bruno" }); listStudents.Add(new Student() { Grade = 33, Name = "Luciana" }); listStudents.Add(new Student() { Grade = 17, Name = "Maria" }); listStudents.Add(new Student() { Grade = 25, Name = "Luana" }); listStudents.Add(new Student() { Grade = 25, Name = "Pedro" }); listStudents.GroupBy(g => g.Name).OrderBy(g => g.Key).SelectMany(g => g.OrderByDescending(x => x.Grade)).ToList().ForEach(x => Console.WriteLine(x.ToString())); } }
quelle
Alternativ können Sie Folgendes tun:
var _items = from a in StudentsGrades group a by a.Name; foreach (var _itemGroup in _items) { foreach (var _item in _itemGroup.OrderBy(a=>a.grade)) { ------------------------ -------------------------- } }
quelle