I have an array with a finite number of items in it. I want to randomly remove items until all the items have been used once.
Example [1,2,3,4,5]
Random number 5 is used, so I don't want that again. Random number 2 is used, so I don't want that again. And so on..
I could have another list of used numbers and check that the new random number is not in it, but that could take a long time when there is only 1 or two 开发者_运维技巧numbers left in the array out of 50.
Is there a way to remove an item from an array in javascript? Does it create a new array and would that be inefficient?
Are arrays the wrong way to do this?
EDIT: A few good answers here. I ended up randomizing the array list and then splicing the first item which is the one I took out.
Use the combination of Math.random()
and splice()
:
var arr = [1, 2, 3, 4, 5],
i;
while ( arr.length ) {
i = Math.floor( Math.random() * arr.length );
alert( arr.splice(i, 1) );
}
Live demo: http://jsfiddle.net/simevidas/n2Bmk/
Update: You can use this function to remove a random item from your array:
function popRandomItem(arr) {
return arr.length ?
arr.splice(Math.floor(Math.random() * arr.length), 1)[0] : null;
}
So, if you have an array x
, then popRandomItem(x)
will remove a random item from that array and return that item. (If x
is an empty array, the function will return null
.)
Live demo: https://jsbin.com/wetumec/edit?js,console
You can use splice()
to remove array elements.
Update
The function below lets you specify an upper and lower bound, and calling the resulting returned function will return a random number until the pool is empty, in which case it will return false
(make sure you detect this with getRandom() === false
).
var getRandomNumberOnce = function(lower, upper) {
var pool = [];
for (var i = lower; i <= upper; i++) {
pool.push(i);
}
return function() {
if (pool.length == 0) {
return false;
}
var randomIndex = Math.floor(Math.random() * pool.length ),
randomNumber = pool[randomIndex];
pool.splice(randomIndex, 1);
return randomNumber;
}
}
jsFiddle.
Usage
var myRandom = getRandomNumberOnce(0, 50);
myRandom(); // 4 (guaranteed to be random) :P http://xkcd.com/221/
I understand you're asking about removing elements but I'm going to go ahead and suggest an alternative way. This way does the same thing you want (getting a random element only once) but doesn't involve removing elements - well, it doesn't have to.
Essentially, randomise the order of your array rather than looking for random elements. Then work your way through the array for the random element you need. Your first random element will be at the 0 index, second random element will be at 1 index, etc.
var array = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14];
array.sort(function(){ return (Math.round(Math.random())-0.5); });
for(var i=0;i<array.length;i++){
$("#list").append('<li>Random element ' + i + ': ' +array[i]);
}
Example: http://jsfiddle.net/jonathon/Re4HK/
Another question talks about randomising a JavaScript array but I just used a basic random sort as it works to illustrate the idea. You might want to look at that if you're concerned about how random your array is.
Sometimes you want a random item and don't care if it is repeated once in a while.
Other times you want to quit when the aray is empty, and see no repeats.
Array.prototype.getRandom= function(cut){
var i= Math.floor(Math.random()*this.length);
return cut? this.splice(i, 1): this[i];
}
精彩评论