Skip to content

Instantly share code, notes, and snippets.

@EvanHahn
Created August 10, 2011 00:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save EvanHahn/1135646 to your computer and use it in GitHub Desktop.
Save EvanHahn/1135646 to your computer and use it in GitHub Desktop.
Choose objects by weight. Free license.
/**
* Choose objects by weight.
* @author Evan Hahn
* @version 1.00
* @param {Object[]} objects An array of objects that each have a "weight" property.
* @param {Number} howMany How many should I choose?
* @returns An array of chosen objects, containing howMany values.
* @example
* chooseByWeight([
* {
* "title": "Apple",
* "weight": 4
* },
* {
* "title": "Banana",
* "weight": 1
* },
* {
* "title": "Coconut",
* "weight": 2
* },
* {
* "title": "Date",
* "weight": 1
* }
* ], 2); // Is likely to return the Apple object and then the Coconut object
*/
var chooseByWeight = function(objects, howMany) {
// Sum the weights
var totalWeight = 0;
var i = objects.length;
while (i --) {
totalWeight += objects[i].weight;
}
// Choose from among them
var chosenOnes = [];
while (chosenOnes.length < howMany) {
// Pick a random number
var tryThis = Math.random() * totalWeight;
// Find the one to stop on
var currentIndex = 0;
var totalSoFar = 0;
while (tryThis > totalSoFar) {
totalSoFar += objects[currentIndex].weight;
if (tryThis > totalSoFar) {
currentIndex ++;
}
}
// Choose it if it hasn't already been chosen
if (chosenOnes.indexOf(objects[currentIndex]) === -1) {
chosenOnes.push(objects[currentIndex]);
}
}
// Return
return chosenOnes;
}
@kensykora
Copy link

There's potentially a big performance issue here, and you're using while loops where for loops should be used instead. Check out my comments here:

https://gist.github.com/47042c834561ba826b2e

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment