Getting a random (or rather, "pseudorandom") number in JavaScript is quite simple. Calling Math.random()
usually gets the job done, but, in some instances you only want a random number to be returned if it hasn’t already been.
For such instances I’ve created a simple function which accepts an array as it’s first parameter. Calling the ‘getItem’ method retrieves a unique random item from the array:
The code:
// @param list: an Array // @param alias: name for getter function, // by default it's "getItem" function RandomList(list, alias) { if (!list) { return; } var length = list.length; this.indexes = []; this.remainingItems = function(){ return this.indexes.length; }; this[alias || 'getItem'] = function(){ var rand = Math.floor(Math.random() * this.indexes.length), item = list[this.indexes[rand]]; this.indexes.splice(rand, 1); return item; }; while (length--) { this.indexes[this.indexes.length] = length; } } |
The second parameter is optional, it let’s you define a custom alias for the main getter function which, by default, is named ‘getItem’.
Usage:
// List of fruit: var fruits = [ 'Apple', 'Banana', 'Orange', 'Melon', 'Grape', 'Pear' ]; // Construct a new random list: var myFruitBasket = new RandomList(fruits); // Retrieve items (randomly): /* 1: */ myFruitBasket.getItem(); // => 'Banana' /* 2: */ myFruitBasket.getItem(); // => 'Apple' /* 3: */ myFruitBasket.getItem(); // => 'Grape' /* 4: */ myFruitBasket.getItem(); // => 'Orange' /* 5: */ myFruitBasket.getItem(); // => 'Pear' /* 6: */ myFruitBasket.getItem(); // => 'Melon' /* 7: */ myFruitBasket.getItem(); // => UNDEFINED // Last item is UNDEFINED because there are no fruit // left in the basket!!! |
As you can see, the function will only return unique random items (never the same one twice).
Another example:
// Every time the button is clicked // get an item from the fruit basket // and report how many are left: var button = document.getElementById('the_button'), // Custom alias ('getFruit'): basket = new RandomList(fruits, 'getFruit'); button.onclick = function() { if (!basket.remainingItems()) { alert('None left!'); } else { alert( basket.getFruit() ); // < We're using the new alias! alert( 'Only ' + basket.remainingItems() + ' left in the basket!'); } } |
Be careful when using it with sparse arrays (e.g. [1,2,null,null,3,null,4]
) because it will be difficult to detect when there are no items remaining.
Thanks for reading! Please share your thoughts with me on Twitter. Have a great day!