在 JavaScript 中生成不重复的随机数

cha*_*i86 1 javascript arrays random numbers

如何确保我不会重复得到随机数?目前,这不起作用。我正在使用本地数组来存储以前的结果。

getUniqueRandomNumber(x){
     var index;
     var viewedIndices = [];
     index = Math.floor(Math.random() * (x));
     if(viewedIndices.includes(index)) 
     {
       viewedIndices.push(index);
       this.getUniqueRandomNumber(x);
     }
     else { 
       console.log(index);
       return index;
    }
 }
Run Code Online (Sandbox Code Playgroud)

Cer*_*nce 5

您需要将viewedIndicies 其持久化,以便进一步的调用getUniqueRandomNumber可以看到之前添加的元素。与跟踪索引相比,仅跟踪所选的简单数字可能会更容易。您可以使用 Set 而不是数组来降低计算复杂度(.hasis O(1).includesis O(N))。

const makeGetUniqueRandomNumber = (x) => {
  const chosenNumbers = new Set();
  return () => {
    if (chosenNumbers.size === x) {
      throw new Error('No more uniques!');
    }
    let num;
    do {
      num = Math.floor(Math.random() * x);
    } while (chosenNumbers.has(num));
    chosenNumbers.add(num);
    return num;
  };
};

const getRand5 = makeGetUniqueRandomNumber(5);
console.log(
  getRand5(),
  getRand5(),
  getRand5(),
  getRand5(),
  getRand5()
);
try {
  getRand5();
} catch(e) {
  console.log(e.message);
}

const anotherGetRand5 = makeGetUniqueRandomNumber(5);
console.log(
  anotherGetRand5(),
  anotherGetRand5(),
  anotherGetRand5(),
  anotherGetRand5(),
  anotherGetRand5()
);
Run Code Online (Sandbox Code Playgroud)

您还可以提前生成整个随机数数组,然后splice每次选择另一个随机数,但是当可能性的数量很大但您只需要几个随机数时,这将是低效的。正确的选择取决于一次会话中所需的唯一数字与随机范围大小的比例。

如果在不理解 ES6 (ES2015) 语法的古老环境中进行开发,那么你可以使用数组代替 Set,并通过 Babel 传递代码:

"use strict";

var makeGetUniqueRandomNumber = function makeGetUniqueRandomNumber(x) {
  var chosenNumbers = [];
  return function () {
    if (chosenNumbers.length === x) {
      throw new Error('No more uniques!');
    }

    var num;

    do {
      num = Math.floor(Math.random() * x);
    } while (chosenNumbers.includes(num));

    chosenNumbers.push(num);
    return num;
  };
};

var getRand5 = makeGetUniqueRandomNumber(5);
console.log(getRand5(), getRand5(), getRand5(), getRand5(), getRand5());

try {
  getRand5();
} catch (e) {
  console.log(e.message);
}

var anotherGetRand5 = makeGetUniqueRandomNumber(5);
console.log(anotherGetRand5(), anotherGetRand5(), anotherGetRand5(), anotherGetRand5(), anotherGetRand5());
Run Code Online (Sandbox Code Playgroud)