Module: Enumerable

Defined in:
lib/weighted_sample.rb

Instance Method Summary collapse

Instance Method Details

#weighted_sample_by(&block) ⇒ Object

Raises:

  • (ArgumentError)


2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# File 'lib/weighted_sample.rb', line 2

def weighted_sample_by &block
  return nil if self.empty?

  weights = self.map(&block)
  raise ArgumentError, 'Weight should Integer' unless weights.all? &Integer.method(:===)

  total_weight = weights.reduce(:+)
  raise ArgumentError, 'Sum of weights should > 0' unless total_weight > 0

  r = rand(total_weight)

  cumlative_weight = 0
  self.zip(weights).each do|obj, weight|
    cumlative_weight += weight
    return obj if r < cumlative_weight
  end
  raise 'Should not reach here'
end