Sam
Sam

Reputation: 313

Javascript: select random element from array that is not equal to 'undefined'

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

Answers (8)

barış çıracı
barış çıracı

Reputation: 1043

arr = arr.filter(function (n) { return n !== undefined });

Upvotes: 1

Diode
Diode

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

Michael Anderson
Michael Anderson

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

jAndy
jAndy

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

Tomas Reimers
Tomas Reimers

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

Kerrek SB
Kerrek SB

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

Phil Rykoff
Phil Rykoff

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

Niet the Dark Absol
Niet the Dark Absol

Reputation: 324620

First I would loop through the array stripping out the undefined values. Then pick an element from the resulting array.

Upvotes: 1

Related Questions