简体   繁体   中英

unique random array javascript

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?

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/

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

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);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM