JS创建具有唯一随机数的数组

时间:2019-01-06 19:56:33

标签: javascript arrays unique

完整的代码看起来像这样,理想情况下,我们有4个div框,需要用随机数ansValue随机填充,其中一个(带有rightAnsId的rightAnsValue)已经完成并且可以正常工作,我设法使其具有唯一性与其他人相比(代码未注释部分)。但是在使其他人变得独特时遇到了问题,我的包装盒中始终保留一些相同的值。在评论中,我尝试解决此问题的一种方法,但可以肯定的是,有一个更简单,更智能的解决方案可以实际工作。如果您能帮助找到一个可以理解的解决方案,我将不胜感激。 (P.S.我已经看到了类似的问题,但是它们要么太难了,要么没有JS就完成了。)

function createAnswers(){
    for(ansId=1; ansId<5; ansId++){
        if(ansId!=rightAnsId){
            for(i=1; i<10; i++){
                digitArray[i-1] = i;
            }
            genNewRandNum();

            // ansArray.length = 3;
            // ansArray.push(ansValue);
            // for(k=0; k<3; k++){
            //     if(ansArray[k] == ansArray[k+1] || ansArray[k] == ansArray[k+2]){
            //         genNewRandNum();
            //         ansArray[k] = ansValue;
            //     }else if(ansArray[k+1] == ansArray[k+2]){
            //         genNewRandNum();
            //         ansArray[k+1] = ansValue;
            //     }else{
            //         break;
            //     }
            // }

            if(ansValue!=rightAnsValue){
                document.getElementById("box" + ansId).innerHTML = ansValue;
            }else{
                genNewRandNum();
                document.getElementById("box" + ansId).innerHTML = ansValue;
            }
        }
    }
}

我生成新数字的方式:

function genNewRandNum(){
    rand1 = digitArray[Math.floor(Math.random() * digitArray.length)];
    rand2 = digitArray[Math.floor(Math.random() * digitArray.length)];
    ansValue = rand1 * rand2;
}

2 个答案:

答案 0 :(得分:0)

用下面的代码替换genNewRandNum()。我已经使用IIFE创建了一个闭合变量已经生成的数字,该数字在返回的函数generateRandomNumber()中可用。

因此,每次执行genNewRandNum()时,它都会对已经生成的数字进行检查,以确保它始终返回1到9之间的唯一值。

var genNewRandNum = (function(){
  var alreadyGeneratedNumbers = {};
  return function generateRandomNumber() {
    var min = Math.ceil(1),
      max = Math.floor(9);
      randomNumber = Math.floor(Math.random() * (max - min + 1)) + min;
    
    if(alreadyGeneratedNumbers[randomNumber]) {
      return generateRandomNumber();
    } else {
      alreadyGeneratedNumbers[randomNumber] = randomNumber;
      return randomNumber;
    }

  }
})();



console.log(genNewRandNum());
console.log(genNewRandNum());
console.log(genNewRandNum());
console.log(genNewRandNum());
console.log(genNewRandNum());
console.log(genNewRandNum());
console.log(genNewRandNum());
console.log(genNewRandNum());
console.log(genNewRandNum());

注意:如果您第十次调用genNewRandNum(),它将抛出错误。因此,如果您有一个用例,需要在返回从1到9的所有数字后将其重置,那么您需要添加代码来处理

答案 1 :(得分:0)

最简单的暴力破解方法是使用接受/拒绝采样。您可以这样做:

uniqueRandomNumbers = function(n, nextRandom)
{
  var nums = {}; var m = 0;

  while(m < n)
  {
    var r = nextRandom();

    if(! nums.hasOwnProperty(r))
    {
      nums[r] = true; m++;
    }
  }

  return Object.keys(nums);
}

在这里,我使用了一个事实,即js对象被实现为哈希映射以获取哈希集。 (这具有将数字转换为字符串的缺点,但是如果您不打算立即对它们进行算术运算,那将不是问题。)

为了获得0到9之间的四个唯一整数,您可以执行以下操作:

uniqueRandomNumbers(4, function() { return Math.floor(Math.random() * 10); })

如果您想要的东西比蛮力好一点(这可能与您的用例无关,但可以帮助某人进行搜索),一种选择是遍历每个元素,并以适当的概率获取或保留它。 this question的答案中概述了这种方法。