Class: WeightedListRank::RankingContext

Inherits:
Object
  • Object
show all
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

Instance Method Summary collapse

Constructor Details

#initialize(strategy = Strategies::Exponential.new) ⇒ RankingContext

Initializes a new RankingContext with an optional ranking strategy.

Parameters:

  • strategy (Strategy) (defaults to: Strategies::Exponential.new)

    the strategy to use for ranking items, defaults to Strategies::Exponential.



10
11
12
# File 'lib/weighted_list_rank/context.rb', line 10

def initialize(strategy = Strategies::Exponential.new)
  @strategy = strategy
end

Instance Attribute Details

#strategyObject (readonly)

@strategy: The strategy used for calculating scores.



6
7
8
# File 'lib/weighted_list_rank/context.rb', line 6

def strategy
  @strategy
end

Instance Method Details

#rank(lists) ⇒ Array<Hash>

Ranks items across multiple lists according to the strategy’s score calculation.

Parameters:

  • lists (Array<List>)

    an array of List objects to be ranked.

Returns:

  • (Array<Hash>)

    a sorted array of item scores, with each item’s details including ID, score details, and total score.



17
18
19
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
# File 'lib/weighted_list_rank/context.rb', line 17

def rank(lists)
  items = {}
  lists.each do |list|
    list.items.each do |item|
      score = strategy.calculate_score(list, item)
      items[item.id] ||= {}
      # Ensure the list_details array exists, then append the new score detail
      items[item.id][:list_details] ||= []
      items[item.id][:list_details] << {list_id: list.id, score: score, weight: list.weight, score_penalty: item.score_penalty}

      # Ensure the total_score is initialized, then add the score
      items[item.id][:total_score] ||= 0
      items[item.id][:total_score] += score
    end
  end

  # Convert hash to a sorted array
  sorted_items = items.map do |id, details|
    {
      id: id,
      # Sort the score_details array by score in descending order before including it
      score_details: details[:list_details].sort_by { |detail| -detail[:score] },
      total_score: details[:total_score]
    }
  end

  # Sort the array by total_score in descending order
  sorted_items.sort_by { |item| -item[:total_score] }
end