Reputation: 313
I have an array that has only had specific keys set. The array will look something like
arr[0] = 'undefined';
arr[1] = '16';
arr[2] = 'undefined';
arr[3] = '13';
arr[4] = 'undefined';
arr[5] = 'undefined';
arr[6] = '24';
arr[7] = 'undefined';
From that particular array I would want to randomly select either 16, 13, or 24.
Is there a good way to do this?
Thanks,
Sam
Upvotes: 3
Views: 2595
Reputation: 1043
arr = arr.filter(function (n) { return n !== undefined });
Upvotes: 1
Reputation: 25135
Randomly select one index and from that index search for a non-undefined element.
function getrandom(arr){
var ri = Math.floor(Math.random() * arr.length);
for(var i=0; i<arr.length; i++){
var ai = (i + ri)%arr.length;
if(arr[ai] != 'undefined'){
return arr[ai];
}
}
}
Upvotes: 1
Reputation: 73480
Here's a way that is unbiased, doesn't create a temporary array and only scans the array once. It's based on reservoir sampling.
function pick_random_value(src)
local count = 0
local value = undefined
for( i=0; i<src.length; ++i)
{
if (src[i]==='undefined') { continue; }
++count;
if ( Math.random() < 1/count ) { value = src[i]; }
}
return value;
end
The downside is that Math.random()
gets called multiple times. There may be ways to reduce that number of calls though.
An upside is that it can be modified to select N unique items rather than just one easily.
Upvotes: 0
Reputation: 235982
(function( src ) {
console.log( src[ ~~(Math.random() * src.length) ] );
}( arr.filter(function( elem ) { return elem !== 'undefined'; }) ));
Demo: http://jsfiddle.net/y7g6x/
This is slightly tricky. What basically happens is, that the array is first filtered for all non 'undefined' values. That new array is then passed into the self-invoking function where we just call a console.log()
on a random element. We need to make sure that our call to Math.random()
does not deliver some floating point value, so I'm using ~~
to cut numbers. Its probably more convinient to use Math.floor()
there.
Upvotes: 0
Reputation: 3292
function randomFromTo(from, to){
return Math.floor(Math.random() * (to - from + 1) + from);
}
var Arr = // You define this
var answer = 'undefined';
while (answer == 'undefined'){
answer = Arr[randomFromTo(0, Arr.length)];
}
Thanks to http://www.admixweb.com/2010/08/24/javascript-tip-get-a-random-number-between-two-integers/
Upvotes: 0
Reputation: 476990
Make a new array consisting of the indexes of the entries of your original array that you wish to consider (e.g. {1, 3, 5}
in your case); then pick a random element (in whichever way that satisfies your statistical requirements) from the index array and then retrieve the corresponding value.
Upvotes: 4
Reputation: 12087
The 'best' way of doing this would be to randomly select one element in a loop. Exit the loop if the selected element is not "undefined".
Upvotes: 2
Reputation: 324620
First I would loop through the array stripping out the undefined
values. Then pick an element from the resulting array.
Upvotes: 1