This class makes it easier to generate a leaderboard that complies with the Standard Competition Ranking system. That is, it takes joint/tied positions into account, and adjusts the positions accordingly.
Take the following list of users and points for example:
User | Points
1 35
2 35
3 50
4 10
5 35
You might be contented with a leaderboard like this:
User | Points | Position
3 50 1
2 35 2
1 35 3
5 35 4
4 10 5
Users 2, 1 and 5 all have the same points, so what makes user 2 come second, and user 5 come fourth? That can't be right!
What you really need is this:
User | Points | Position
3 50 1
2 35 2
1 35 2
5 35 2
4 10 5
Which you can do with the code in this gist!
ranking_data = {...} # hash representation of above user/points table
leaderboard = StandardCompetitionRankings.new(ranking_data, :rank_by => :points, :sort_direction => :desc)
better_leaderboard = leaderboard.calculate
If you don't want any sorting applied because you want to roll your own or whatever, set the :sort_direction
parameter to nil
or false
.
After all that, it will append a field called position
to your dataset, which contains your now standardised rankings, and return the whole thing. :)
@leemachin, thanks for sharing. While this is great for unstructured data, it's worth mentioning that if you can use SQL, it's a much simpler implementation and faster. Here's a sample which also supports pagination.
Keep in mind I've modified this from my working version to make it more generic, so I can't guarantee there won't be any bugs.