Class: WeightedListRank::RankingContext
- Inherits:
-
Object
- Object
- WeightedListRank::RankingContext
- Defined in:
- lib/weighted_list_rank/context.rb
Overview
RankingContext is responsible for applying a ranking strategy to a collection of lists and their items. It aggregates scores for each item across all lists, based on the provided strategy.
Instance Attribute Summary collapse
-
#list_count_penalties ⇒ Object
readonly
@strategy: The strategy used for calculating scores.
-
#strategy ⇒ Object
readonly
@strategy: The strategy used for calculating scores.
Instance Method Summary collapse
-
#initialize(strategy = Strategies::Exponential.new, list_count_penalties: {}) ⇒ RankingContext
constructor
Initializes a new RankingContext with an optional ranking strategy and list count penalties.
-
#rank(lists) ⇒ Array<Hash>
Ranks items across multiple lists according to the strategy's score calculation.
Constructor Details
#initialize(strategy = Strategies::Exponential.new, list_count_penalties: {}) ⇒ RankingContext
Initializes a new RankingContext with an optional ranking strategy and list count penalties.
12 13 14 15 |
# File 'lib/weighted_list_rank/context.rb', line 12 def initialize(strategy = Strategies::Exponential.new, list_count_penalties: {}) @strategy = strategy @list_count_penalties = list_count_penalties end |
Instance Attribute Details
#list_count_penalties ⇒ Object (readonly)
@strategy: The strategy used for calculating scores. @list_count_penalties: Hash mapping list counts to penalty percentages (e.g., => 0.50, 2 => 0.25)
7 8 9 |
# File 'lib/weighted_list_rank/context.rb', line 7 def list_count_penalties @list_count_penalties end |
#strategy ⇒ Object (readonly)
@strategy: The strategy used for calculating scores. @list_count_penalties: Hash mapping list counts to penalty percentages (e.g., => 0.50, 2 => 0.25)
7 8 9 |
# File 'lib/weighted_list_rank/context.rb', line 7 def strategy @strategy end |
Instance Method Details
#rank(lists) ⇒ Array<Hash>
Ranks items across multiple lists according to the strategy's score calculation.
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/weighted_list_rank/context.rb', line 20 def rank(lists) items = {} # Strategies subclassing Strategy always have this; the fallback covers # duck-typed strategies that only define #calculate_score. batch_capable = strategy.respond_to?(:calculate_scores) lists.each do |list| list_items = list.items scores = if batch_capable strategy.calculate_scores(list) else list_items.map { |item| strategy.calculate_score(list, item) } end list_id = list.id weight = list.weight list_items.each_with_index do |item, index| score = scores[index] details = (items[item.id] ||= {list_details: [], total_score: 0}) details[:list_details] << {list_id: list_id, score: score, weight: weight, score_penalty: item.score_penalty} details[:total_score] += score end end apply_penalties = !list_count_penalties.empty? # Convert hash to a formatted array formatted_items = items.map do |id, details| list_details = details[:list_details] total_score = details[:total_score] # Apply list count penalties if configured if apply_penalties && (penalty = list_count_penalties[list_details.length]) total_score *= (1 - penalty) end { id: id, # Sort the score_details array by score in descending order before including it score_details: list_details.sort_by { |detail| -detail[:score] }, total_score: total_score } end # Sort the array by total_score in descending order formatted_items.sort_by { |item| -item[:total_score] } end |