Skip to content

Instantly share code, notes, and snippets.

@sco
Created September 22, 2008 18:32
Show Gist options
  • Save sco/12089 to your computer and use it in GitHub Desktop.
Save sco/12089 to your computer and use it in GitHub Desktop.
class Array
def weighted_random(weight_method=:weight)
return nil if empty? # return nil if there's no elements
elements = sort_by { Kernel.rand } # shuffle the elements.
weights = elements.map(&weight_method) # get the weight for each element (e.g.: 5, 10, 2, 0, 1, 5).
point = Kernel.rand * weights.sum # pick a random point between zero and the sum of the weights.
elements.zip(weights).each do |e, weight| # walk through each element,
return e if weight >= point # and if its weight is >= the point, return it
point -= weight # otherwise subtract the element's weight from the point
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment