2017-08-23 1 views
0

Ich habe die folgende Liste, die aus einer Liste von Namen und Noten bestehen. Die Partituren I verwendet Linq bekam die Summe der Punkte für die Liste des peope zu bekommen:Linq Liste Ranking in C#

Name Score 
    Ed 5 
    John 6 
    Sara 7 
    Dean 3 
    Nora 4 

So war ich die Liste Gruppe in der Lage und die Summen, aber jetzt versuche ich, diese auf der Grundlage des Rang Ergebnis. So versuche ich, die Liste unten zu bekommen:

Rank Name Score 
1 Sara 7 
2 John 6 
3 Ed 5 
4 Nora 4 
5 Dean 3 

Aber der Linq-Code Ich verwende scheint nicht für mich immer die richtigen Reihen zu werden.

Hier ist mein Code, um die Liste für die Herstellung und die Summen machen und Ranking:

public class Person 
    { 

     public int Rank { get; set; } 
     public string Name { get; private set; } 
     public int Score { get; set; } 

     public Person(int rank, string name, int score) 
     { 
      Rank = rank; 
      Name = name; 
      Score = score; 

     } 
    } 

    public ObservableCollection<Person> Persons { get; set; } 
    public MainWindow() 
    {    
Persons = new ObservableCollection<Person>(); 
     var data = lines.Select(line => { 
     var column = line.Split(','); 
     var name = column[0]; 
     int score = int.Parse(column[1]); 
     int rank =0; 
     return new { name, score, rank }; 
    }); 

     var groupedData = data.OrderByDescending(x => x.score).GroupBy(p => p.name).Select((g, i) => new { name = g.Key, rank=i+1, score = g.Sum(p => p.score)}); 

    var persons = groupedData.Select(p => new Person(p.rank, p.name, p.score)); 

    foreach (var person in persons) { 
     Persons.Add(person); 
    } 
    datagrid.ItemsSource = Persons; 
} 

Ich würde nur gerne wissen, wie richtig Reihen in Linq aufzunehmen.

Antwort

5

Sie müssen die OrderByDescending die groupedData (die eine Gesamtpunktzahl hat), anstatt die Rohdaten mit nicht summierten, einzelnen Punkten.

var persons = groupedData.Select(p => new Person(p.rank, p.name, p.score)).OrderByDescending(x => x.Score); 

bearbeiten: (den richtigen Rang in Person.Rank setzen)

var groupedData = data.GroupBy(p => p.name).Select(g => new { name = g.Key, score = g.Sum(p => p.score)}).OrderByDescending(x => x.score); 
var persons = groupedData.Select((p,i) => new Person(i+1, p.name, p.score)); 
+0

Grüße, Dank für Ihre Antwort danken. Ich habe Ihre vorgeschlagene Lösung versucht, aber ich bekomme immer noch nicht die richtige Rangordnung: S –

+0

Der Rang ist in der Listenposition kodiert, ich werde die Antwort aktualisieren, um es in 'Person.Rank' zu liefern – Haukinger

+0

Perfekt! Jetzt muss ich herausfinden, wie man das Ranking für diejenigen, die die gleiche Punktzahl haben, korrigiert. Vielen Dank :) –

0

fragte ich eine ähnliche Frage an diese eine Weile zurück. Mein Problem war, dass Leute, die die gleiche Punktzahl haben, der Person den falschen Rang zuweisen. Mit Ihrem aktuellen Code, wenn John auch eine Punktzahl von 7 hätte, wäre er auf Platz 2, da Sie nach Punktzahl sortieren und einfach seine Position in der Liste verwenden, wenn er wirklich für # 1 gebunden ist.

war hier meine Frage und Lösung: Get the index of item in list based on value

+0

Vielen Dank für Ihre Antwort. Können Sie bitte die Lösung erklären, da ich nicht verstanden habe, wie die Implementierung das Problem gelöst hat :) –