unique random array javascript

2020-05-09 22:08发布

问题:

I am trying to create an array of 6 unique random numbers out of an array that the user gave his max value and min value (no lower then 0 and no higher then 37). What is incorrect?

    function randCalc(maxVal,minVal)
    {
        var maxVal = document.getElementById("maxRange").value;
        var minVal = document.getElementById("minRange").value;
        var tmpArray = new Array(6) ;
        tmpArray = [0];
        var realArray = new Array(6);
        realArray = tmpArray;
        if ((maxVal - minVal) < 6)
        {
            alert("</br>The difference cannot be lower then 6");
        }
        if (minVal<1)
        {
            alert("</br>The min value cannot be lower then 1");
        }
        if (maxVal>37)
        {
            throw alert("</br>The higher value cannot be higher then 37") ;
        }

        if(minVal>0 && ((maxVal-minVal)>=6)&& (maxVal<=37) )
        {
            document.writeln("</br>The random numbers are: ");
            for(i=0;i<=(6);i++)
            {
                var randLotto = Math.floor(Math.random() * (maxVal - minVal + 2) + minVal);
                tmpArray[i] = randLotto;
            }
            for(var j=0;j<=maxVal;j++)
            {
               for(var k=0;k<6;k++)
               {
                   if(tmpArray[j]==realArray[k])
                   {
                       j++;
                   }
                   else if(tmpArray[j]!=realArray[k])
                   {
                       realArray[k]=tmpArray[j];
                   }
               }
                if(realArray[6]!=null)
                {
                    break;
                }
            }
        }
    }

Any idea how to make it work?

回答1:

Here's a core function for creating N random numbers between a min and max value.

function randCalc(maxVal, minVal, numRandoms) {
    var max = Math.max(maxVal, minVal);
    var min = Math.min(maxVal, minVal);
    // create a set to keep track of numbers we've already used so
    // we don't repeat any random numbers
    var set = {};
    var randoms = [];
    var rand;
    // prevent infinite loop if not given enough range
    if (max - min < numRandoms) {
        return randoms;
    }
    while (randoms.length < numRandoms) {
        rand = Math.floor((Math.random() * (max - min + 1) + min));
        // if we haven't already used this random number
        // then put it in our output array and add it to the set
        if (!(rand in set)) {
            randoms.push(rand);
            set[rand] = true;
        }
    }
    return randoms;
}

This function has nothing to do with the DOM or any particular limits of your problem. You can then wrap this with another function that retrieves info from the DOM, checks to see if everything is in range and then calls this core function.

function makeRandoms() {
    // retrieve DOM values and convert them to numbers
    var maxVal = document.getElementById("maxRange").value;
    var minVal = document.getElementById("minRange").value;
    if (!maxVal || !minVal) {
        alert("You must specify both a minimum and maximum value");
        return;
    }
    // convert both to numbers
    maxVal = parseInt(maxVal, 10);
    minVal = parseInt(minVal, 10);
    if (minVal < 1) {
        alert("The min value cannot be lower then 1");
        return;
    }
    if (maxVal > 37) {
        alert("The higher value cannot be higher then 37");
        return;
    }
    if (maxVal - minVal < 6) {
        alert("The difference cannot be lower then 6");
        return;
    }
    var randoms = randCalc(maxVal, minVal, 6);
    // output the randoms array here
    document.getElementById("output").innerHTML = JSON.stringify(randoms);
}

This makes a reusable function for generating N random values and keeps that utility function completely separate from your code that accesses the DOM in one particular page. Because of the way this uses a set to keep track of the used random numbers, this is scalable to very large numeric ranges or very large numbers of random numbers when some other algorithms that prebuild a list of all possible outputs are not as scalable.

Working demo: http://jsfiddle.net/jfriend00/48kCg/



回答2:

Here is a JS function, more simple, that does what you pretend:

function randCalc(maxVal,minVal){
    var text = "";
    var possible = [];
    for(var i = minVal; i < maxVal; i++){
        possible.push(i);
    }

    for( var i=0; i < 6; i++ ){
        if(text.length == 6){ 
            return text;
        }       

        text += possible[Math.floor(Math.random() * possible.length)];
        if(text > 6){
            text = text.substring(0, 6);
        }
    }
    return text;
}


回答3:

It all looks pretty complicated. You can create an array with [n] random numbers between 0 and [max] using:

function createArrayWithUniqueRandomNumbers(n, max) {
  var checkobj = {}
     ,arr = [];

  while (arr.length < n) {
      var x = Math.floor(Math.random()*(max+1));
      if (!(x in checkobj)) {
          checkobj[x] = 1;
          arr.push(x);
      }
  }

  //sorting for convenience
  return arr.sort(function(a,b){return a-b;});
}
// usage
var myarr = createArrayWithUniqueRandomNumbers(6, 37);