我有这个:
var Utilities = (function (array, maxN) {
function generateRandomNumber(array, maxN) {
let randomN = Math.floor(Math.random() * maxN) + 0;
if(!array.includes(randomN)) {
console.log(maxN);
if(array.length == maxN) {
console.log('max reached');
array.length = 0;
return;
}
else {
array.push(randomN);
}
}
else {
randomN = generateRandomNumber(array, maxN);
}
return randomN;
}
return {
generateRandomNumber: generateRandomNumber
};
})();
export default Utilities;
并且在点击时使用它:
function getRandomNumber(arr) {
let randomN = Utilities.generateRandomNumber(arr, 5);
return randomN;
}
然而,当达到5的长度时,我得到:(虽然我正在清除阵列) 我试图生成一个随机数,但我不想重复它,所以我将它存储在一个数组中,以检查它是否已经生成。但是我遇到的问题是(即使长度为=到最大数时我正在清除数组)我得到了“错误”附加
答案 0 :(得分:2)
然而,当达到5的长度时,我得到一个堆栈溢出,虽然我正在清除数组
不,你没有清除阵列 - 只有当你找到一个新的随机数(不包括在数组中)时才会发生这种情况,当阵列已满时,这当然不会发生。您需要在开头进行长度检查:
function generateRandomNumber(array, maxN) {
if (array.length == maxN) {
console.log('max reached');
array.length = 0;
return;
}
let randomN = Math.floor(Math.random() * maxN) + 0;
if (!array.includes(randomN)) {
array.push(randomN);
console.log(maxN);
return randomN;
} else {
return generateRandomNumber(array, maxN);
}
}
当然,这种通过尝试和错误生成新随机数的方法通常是低效的,并且一旦maxN
非常大并且array
几乎已满,将采取太多步骤。如果迭代实现为递归,则最终会出现堆栈溢出。
答案 1 :(得分:0)
这是因为你应该在看到它不在array
时将项目推入数组中,这样使数组达到最大长度的项目也会清除array
。 1}}。
现在的方式,使数组达到最大值的.push()
不会清除数组,因此在下次调用时,无论生成什么数字都将包含在数组中,递归总是发生。
function generateRandomNumber(array, maxN) {
let randomN = Math.floor(Math.random() * maxN);
if(!array.includes(randomN)) {
if(array.push(randomN) == maxN) {
console.log('max reached');
array.length = 0;
}
return randomN;
} else {
return generateRandomNumber(array, maxN);
}
}
我还通过立即返回递归调用来进行正确的尾调用,而不依赖于当前作用域中的任何变量。我还利用.push()
返回新.length
这一事实,因此其返回值可用于比较。
我可能也会重新安排它以使用积极的条件。
function generateRandomNumber(array, maxN) {
let randomN = Math.floor(Math.random() * maxN);
if(array.includes(randomN)) {
return generateRandomNumber(array, maxN);
}
if(array.push(randomN) == maxN) {
console.log('max reached');
array.length = 0;
}
return randomN;
}
就个人而言,我认为该函数应该使用自己的数组。我将摆脱array
参数,并将var array = [];
放在最外面的IIFE函数中。
由于需要重复使用,因此您可以创建一个工厂函数,该函数生成具有自己的数组和最大长度的唯一函数。
function makeNumberGenerator(maxN) {
var array = [];
return function generateRandomNumber() {
let randomN = Math.floor(Math.random() * maxN);
if(array.includes(randomN)) {
return generateRandomNumber(array, maxN);
}
if(array.push(randomN) == maxN) {
console.log('max reached');
array.length = 0;
}
return randomN;
}
}
然后要使用其中一个,首先要为所需大小创建一个数字生成器:
var randomGen5 = makeNumberGenerator(5);
然后在没有参数的情况下使用它,因为它已经有最大值和数组。
var num = randomGen5(); // 2 (or whatever)
这是一种更有效的算法,用于从范围产生随机数:
function makeNumberGenerator(maxN) {
// Add some code to ensure `maxN` is a positive integer
var array = [];
return function generateRandomNumber() {
if(!array.length) {
array = Array.from(Array(maxN), (_, i) => i);
}
return array.splice(Math.floor(Math.random() * array.length), 1)[0];
}
}