Sha256: 6cc36beef782c1e97dd3f11b4455e3eb1c129dffa340e0995f457410a5dfb125

Contents?: true

Size: 1.99 KB

Versions: 8

Compression:

Stored size: 1.99 KB

Contents

# Extends the Array class with a function used to randomly choose elements.  Note that if you are using Rails, ActiveSupport recently was updated to include a similar
# function.  This code checks for the presence of that method and does not try to replace it.  They work the same though so no worries.

module RandomData
  module ArrayRandomizer
  
    # Randomly chooses an element from an array
    # >> [1,2,3].rand = 3 
    # [].rand = nil

    def rand
      return self[Kernel.rand(self.size)]
    end

    # Takes an array of non-negative weights
    # and returns the index selected by a 
    # roulette wheel weighted according to those
    # weights.
    # If a block is given then k is used to determine
    # how many times the block is called.  In this
    # case nil is returned.
    def roulette(k=1)
      wheel = []
      weight = 0
      # Create the cumulative array.
      self.each do |x|
        raise "Illegal negative weight #{x}" if x < 0
        wheel.push(weight += x)
      end
      # print "wheel is #{wheel.inspect}\n";
      # print "weight is #{weight.inspect}\n";
      raise "Array had all zero weights" if weight.zero?
      wheel.push(weight + 1) #Add extra element
      if block_given?
        k.times do 
          r = Kernel.rand() # so we don't pick up that from array.
          # print "r is #{r.inspect}\n";
          roll = weight.to_f * r
          # print "roll is #{roll.inspect}\n";
          0.upto(self.size - 1) do |i|
            if wheel[i+1] > roll
              yield i 
              break
            end # if
          end # upto
        end # if block_given?
        return nil
      else
        r = Kernel.rand() # so we don't pick up that from array.
        # print "r is #{r.inspect}\n";
        roll = weight.to_f * r
        # print "roll is #{roll.inspect}\n";
        0.upto(self.size - 1) do |i|
          return i if wheel[i+1] > roll
        end
      end
    end

  end

end

unless Array.respond_to?(:rand)
  Array.send :include, RandomData::ArrayRandomizer
end

Version data entries

8 entries across 8 versions & 4 rubygems

Version Path
jjulian-random_data-1.5.0 lib/random_data/array_randomizer.rb
tomharris-random_data-1.5.1 lib/random_data/array_randomizer.rb
random_data-1.6.0 lib/random_data/array_randomizer.rb
random_data-1.5.2 lib/random_data/array_randomizer.rb
malvestuto_random_data-1.5.2 lib/random_data/array_randomizer.rb
malvestuto_random_data-1.5.1 lib/random_data/array_randomizer.rb
random_data-1.5.1 lib/random_data/array_randomizer.rb
random_data-1.5.0 lib/random_data/array_randomizer.rb