Using Math Random to make a random number appear only ONCE each


#1

So I created a code to randomly return numbers 0-8 only if the number wasn't already shown in the list. The code works a few times then randomly returns undefined although the number isn't in the list. The code I used is below:

var used=[];
    function randy(){
        var n=Math.floor(Math.random()*9);
        if(used.indexOf(n)>-1){
            randy();
        }
        else{
            used.push(n);
            return n;
        }
    }

The strangest thing is I replaced return n with show.innerHTML= listName[n] the code works fine and will random select items 0-8. Can someone please tell me how to fix this or provide an explanation.


#2

Why it doesn't do what you want:

Your function returns undefined because in one of the cases you do not have a return statement, thus the return value is undefined.

Some comments on the design:

  • You should avoid keeping data outside the function, that's not how functions should behave.
  • An alternative approach that should be mostly equivalent is to generate the full sequence each time the function is called.
  • Another alternative is to have a constructor create objects that produces each next value until it has been exhausted, this object would have a next method.
  • It would be preferable to use random to pick next number instead of generating random numbers until you've come up with one that hasn't been picked yet.