3

What is the best way to sort by a value, find the index of the item for its rank, but take into account ties. The index for 5th place could have two items so 6th is skipped and the next iteration starts at 7th. Is the best way to do this to do a group by and track an index?

return teamTournamentResults
.OrderByDescending(t => t.RankingPoints)
.Select((item, index) => new { Item = item, Index = index })
.Select(q => new TeamSummaryResultsModel
                {
                                DivisionRanking = q.Index + 1,
                                RankingPoints= q.Item.RankingPoints,
Mike Flynn
  • 22,342
  • 54
  • 182
  • 341

2 Answers2

1

Please, read my comment to the question.

Have a look at example:

List<int> mi = new List<int>(){1,2,2,5,6,7,7,7,8,9,10,10};

var qry = mi
        .Select(g=>new
            {
                number = g,
                rank = (from i in mi where i>g select i).Count()+1
            });

Result:

number rank
1      12 
2      10 
2      10 
5      9 
6      8 
7      5 
7      5 
7      5 
8      4 
9      3 
10     1 
10     1 

Other useful resources:

Converting SQL Rank() to LINQ, or alternative

LINQ Query with grouping and ranking

Implementing RANK OVER SQL Clause in C# LINQ

Community
  • 1
  • 1
Maciej Los
  • 8,468
  • 1
  • 20
  • 35
0

Do you need to find out the rank for a single item for all of them? If you need it just for a single one, then O(n log n) sorting is not necessary.

You can use a simple for loop in linear time to count the items smaller and larger, and a list of equal items. Then you just apply the same procedure to the list of equals items but compare by team name to get a consistent ordering.

var equalItems = new List<Team>();
int smaller = 0, bigger = 0;
var myItem = ...;
foreach(var item in teamTournametResults)
    if (item.RankingPoints > myItem.RankingPoints)
        ++bigger;
    else
    {
        if (item.RankingPoints < myItem.RankingPoints)
              ++smaller;
        else if (item != myItem)
            equalItems.Add(item);
    }

foreach(var item in equalItems)
    if (item.Name.CompareTo(myItem.Name) > 0)
        ++bigger;
    else
        ++smaller;

The resulting rank is now stored in bigger.

Isolin
  • 845
  • 7
  • 20