lib/roulette-wheel-selection.rb in roulette-wheel-selection-1.0.1 vs lib/roulette-wheel-selection.rb in roulette-wheel-selection-1.0.2

- old
+ new

@@ -17,16 +17,44 @@ hash = array.map{|v| [v, v[key]] }.to_h return sample_from_hash(hash) end def sample_from_hash(hash) - total_rate = hash.values.inject(&:+) || 0 - return if total_rate == 0 - random_seed = rand(total_rate) - hash.each do |obj, rate| - return obj if random_seed < rate - random_seed -= rate - end + RouletteWheelSelection.new(hash).sample + end + end + + def initialize(hash) + @hash = hash + @total_rate = hash.values.inject(&:+) || 0 + end + + def sample(num = 1) + return if @total_rate == 0 + return if num < 1 + return sample_n_objects(num) if num > 1 + return sample_an_object(@total_rate, @hash) + end + + private + + def sample_n_objects(num) + hash = @hash.clone + total_rate = @total_rate + num = total_rate if num > total_rate + return Array.new(num) do + obj = sample_an_object(total_rate, hash) + hash[obj] -= 1 + total_rate -= 1 + next obj + end + end + + def sample_an_object(total_rate, hash) + random_seed = rand(total_rate) + hash.each do |obj, rate| + return obj if random_seed < rate + random_seed -= rate end end end