Ram Singh
Ram Singh

Reputation: 6928

Listing after implementing ranking skipping numbers

I am trying to achieve ranking functionality as below:

 Name      Points      rank
 ram       9            1  
 kamal     9            1
 preet     8            2
 lucky     7            3
 kishan    6.5          4
 devansh   6            5
 neha      6            5

I have used below code to achieve this:

finalResult = finalResult.OrderByDescending(i => i.points).ThenBy(i => i.academy).ToList();
finalResult = finalResult.AsEnumerable() // Client-side from here on
    .Select((player, index) => new RankingEntity()
    {

        competitorid = player.competitorid,
        firstname = player.firstname,
        lastname = player.lastname,
        academy = player.academy,
        points = player.points,
        place = player.place,
        eventId = player.eventId,
        eventname = player.eventname,
        categoryname = player.categoryname,
        Rank = index + 1
    }).ToList();

var t = (from i in finalResult
         let rank = finalResult.First(x => x.points == i.points)
         select new
         {
             Col1 = i,
             Rank = rank.Rank
         }).ToList();

List<RankingEntity> ttt = new List<RankingEntity>();

foreach (var item in t)
{
    var a = item.Col1;
    var row = new RankingEntity();
    row.competitorid = a.competitorid;
    row.firstname = a.firstname;
    row.lastname = a.lastname;
    row.academy = a.academy;
    row.points = a.points;
    row.place = a.place;
    row.eventId = a.eventId;
    row.eventname = a.eventname;
    row.categoryname = a.categoryname;
    row.Rank = item.Rank;

    ttt.Add(row);
}

And i am getting result like below:

Check this

Please help what i am doing wrong.

Upvotes: 0

Views: 39

Answers (1)

Gilad Green
Gilad Green

Reputation: 37281

What you are trying to achieve is a ranking of a "group" so group the results by the points and then order the groups. For each item in the group give the same rank.

finalResult.GroupBy(item => item.Points) // Group by points
           .OrderDescendingBy(g => g.Key) // Order the groups
           .Select((g, index) => new { Data = g, GroupRank = index + 1}) // Rank each group
           .SelectMany(g => g.Data.Select(item => new RankingEntity
           {
               /* properties of each item */
               Rank = g.GroupIndex
           }); // Flatten groups and set for each item the group's ranking

The problem in your method is that you give the ranking for individual items and not the group. Then when you retrieve the rank for the group (from i in finalResult let rank = finalResult.First(x => x.points == i.points)...) you actually set for each item in the group the ranking of one of the elements in it. Therefore, if you first got the last item of the group - that will be the Rank value of each item in it.


Also notice that in the first line of your code you use ToList. Therefore there is not need to use AsEnumerable in the line under it - it is already a materialized in memory collection.

Upvotes: 1

Related Questions