Created
June 12, 2015 07:10
-
-
Save Systho/b9987f44041b934b1ef5 to your computer and use it in GitHub Desktop.
Podium class to handle ranking, might be useful in the future
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Podium | |
def initialize(results) | |
@results = results | |
end | |
def rank_for(key) | |
score = results[key] | |
return 0 if score.nil? | |
index = reverse_results_hash.keys.index(score) | |
(0...index).to_a.sum{|prev_index| ranked_at(prev_index ).size } + 1 | |
end | |
def ranked(rank) | |
return [] unless (1..max_rank).cover?(rank) | |
reverse_results_array.each do |_, keys| | |
return keys if keys.length >= rank | |
rank -= keys.length | |
end | |
[] | |
end | |
def max_rank | |
results.size | |
end | |
private | |
attr_reader :results | |
def ranked_at(index) | |
reverse_results_array[index].last | |
end | |
def reverse_results_hash | |
@reverse_results_hash ||= results.keys.group_by{|k| results[k] }.sort.reverse!.to_h | |
end | |
def reverse_results_array | |
@reverse_results_array ||= reverse_results_hash.to_a | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'podium' | |
RSpec.describe Podium do | |
let(:results){ Hash.new } | |
subject { Podium.new(results)} | |
describe "#rank_for(key)" do | |
it "returns the position if all the keys have different scores" do | |
results[:blue]= 10 | |
results[:red]= 5 | |
results[:green]= 1 | |
expect(subject.rank_for(:blue)).to eq 1 | |
expect(subject.rank_for(:red)).to eq 2 | |
expect(subject.rank_for(:green)).to eq 3 | |
end | |
it "handles keys having the same score by allowing them to all have the lowest possible rank" do | |
results[:blue]= 10 | |
results[:red]= 5 | |
results[:white]= 5 | |
results[:green]= 1 | |
expect(subject.rank_for(:blue)).to eq 1 | |
expect(subject.rank_for(:red)).to eq 2 | |
expect(subject.rank_for(:white)).to eq 2 | |
expect(subject.rank_for(:green)).to eq 4 | |
end | |
it "returns 0 if the key is not part of the results" do | |
expect(subject.rank_for(:unknown)).to eq 0 | |
end | |
end | |
describe "#ranked(rank)" do | |
it "returns the keys at the position if all the keys have different scores" do | |
results[:blue]= 10 | |
results[:red]= 5 | |
results[:green]= 1 | |
expect(subject.ranked(1)).to eq [:blue] | |
expect(subject.ranked(2)).to eq [:red] | |
expect(subject.ranked(3)).to eq [:green] | |
end | |
it "handles keys having the same score by allowing them to be retrieved by any of the possible rank" do | |
results[:blue]= 10 | |
results[:red]= 5 | |
results[:white]= 5 | |
results[:green]= 1 | |
expect(subject.ranked(1)).to eq [:blue] | |
expect(subject.ranked(2)).to eq [:red, :white] | |
expect(subject.ranked(3)).to eq [:red, :white] | |
expect(subject.ranked(4)).to eq [:green] | |
end | |
it "returns an empty array if the rank is higher than the number of results" do | |
expect(subject.ranked(1)).to eq [] | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment