3

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

8 Answers 8

4

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.

Sign up to request clarification or add additional context in comments.

Comments

2

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".

1 Comment

This is potentially very inefficient if you have a huge array where most values are "undefined".
1

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

Comments

1

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];
     }
   }
}

Comments

1

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

Comments

0
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/

Comments

0
(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.

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.