2015-02-10 8 views
5

Ich versuche, meine Liste in verschiedene Gruppen aufzuteilen, basierend auf einem bestimmten Wert, den jedes Element in der Liste hat, und finde dann den Durchschnitt eines anderen Wertes in diesen Gruppen.Durchschnittswert von Gruppen mit LINQ abrufen

besser, es zu setzen, habe ich eine Liste von Studenten:

List<Student> students = new List<Student> { 
    new Student { Name="Bob", Level=Level.Sophomore, GPA=3.2f }, 
    new Student { Name="Cathy", Level=Level.Freshman, GPA=3.6f }, 
    new Student { Name="James", Level=Level.Senior, GPA=3.8f }, 
    new Student { Name="Jessica", Level=Level.Senior, GPA=3.7f }, 
    new Student { Name="Derek", Level=Level.Junior, GPA=2.8f }, 
    new Student { Name="Sam", Level=Level.Junior, GPA=3.1f } 
}; 

Und ich möchte, dass sie durch ihre Klassenstufe zu einer Gruppe, so werden sie in Freshman, Sophomore, Junior, und Senior gruppiert werden. Und dann möchte ich den Durchschnitt GPA für diese Gruppen bekommen.

So eine mögliche Ergebnismenge für diese Schüler wäre:

Senior: 3.7 
Junior: 2.9 
Sophomore: 3.2 
Freshman : 3.6 

ich nicht ganz so sicher bin, wie wenn darum, dieses Ergebnis zu gehen. Ich habe Dinge wie students.GroupBy(x => x.Level).Average(); versucht, aber es funktioniert nicht.

Alle Gedanken dazu würden sehr geschätzt werden. Vielen Dank!

Antwort

13

Sie haben eine zusätzliche Select zu verwenden, so dass Sie suchen etwas wie folgt aus:

var result = students.GroupBy(s => s.Level) 
        .Select(g => new {Level=g.Key, Avg=g.Average(s => s.GPA)}); 

Select(g => new {...}) für jede Gruppe eine Instanz eines neuen anonymen Typs erzeugt.

  • Level, die die Key Eigenschaft der Gruppe
  • Avg, die die durchschnittliche GPA der Gruppe ist

einfach "vorstellen," es gibt ist:

Diese Art zwei Eigenschaften Dieser Typ wird (mehr oder weniger) verwendet:

class GroupAverage 
{ 
    public Level Level { get; set; } 
    public float Avg { get; set; } 
} 

var result = students.GroupBy(s => s.Level) 
        .Select(g => new GroupAverage { Level=g.Key, Avg=g.Average(s => s.GPA) }); 

aber es hat einfach keinen Namen.


result ist jetzt:

enter image description here

Fühlen Sie sich frei um die Werte zu runden, wenn Sie benötigen.


Um die Level mit dem höchsten Durchschnitt zu erhalten, verwenden Sie einfach

var highest = result.OrderByDescending(a => a.Avg).First().Level; 

(Beachten Sie, dass dies zum Absturz, wenn es keine Einträge in students sind)

+0

Können Sie erklären, was diese Abfrage macht? Ich verstehe das neue {Level = g.Key, Avg = g.Average (s => s.GPA)} nicht so gut. – user3113376

+0

Er wählt ein anonymes Objekt aus seiner vorherigen Gruppe mit 2 Eigenschaften aus: 1 der Schlüssel der Gruppierung, welcher die Ebene ist. Die zweite Eigenschaft ist eine Aggregation auf der Gruppierung, in diesem Fall nimmt er den Durchschnittswert aller Schüler GPA in dieser Gruppierung. – Marco

+0

Gruppierung nach Ebene und Auswahl eines neuen anonymen Objekts mit zwei Werten, dem Schlüsselwert (generiert durch die Funktion group()) und dem Durchschnitt des GPA. – Luke

0

Check this out:

students.GroupBy(s => s.Level, s => s.GPA, 
       (level, scores) => new { Level = level, Avg = scores.Average() } 
Verwandte Themen