我有以下功能
function randomNum(max, used){
newNum = Math.floor(Math.random() * max + 1);
if($.inArray(newNum, used) === -1){
console.log(newNum + " is not in array");
return newNum;
}else{
return randomNum(max,used);
}
}
基本上我创建了一个介于 1 - 10 之间的随机数,并通过将其添加到数组并检查新创建的数字来检查该数字是否已经创建。我通过将它添加到变量来调用它..
UPDATED:
for(var i=0;i < 10;i++){
randNum = randomNum(10, usedNums);
usedNums.push(randNum);
//do something with ranNum
}
这有效,但在 Chrome 中我收到以下错误:
Uncaught RangeError: Maximum call stack size exceeded
我猜这是因为我在内部调用函数太多次了。这意味着我的代码不好。
有人可以帮我解决逻辑吗?确保我的号码不重复的最佳方法是什么?
原文由 user1214678 发布,翻译遵循 CC BY-SA 4.0 许可协议
如果我理解正确,那么您只是在寻找数字 1-10 的排列(即没有重复的随机数字)?也许尝试生成这些数字的随机列表,一次,在开始时,然后就通过这些数字来解决?
这将计算
nums
中数字的随机排列:因此,例如,如果您正在寻找 1 - 20 之间的随机数,这些随机数也是偶数,那么您可以使用:
然后通读
ranNums
以回忆随机数。正如您在方法中发现的那样,这不会导致查找未使用的号码的时间越来越长。
编辑:阅读 本文 并在 jsperf 上运行测试后,似乎更好的方法是 Fisher–Yates Shuffle:
基本上,它通过避免使用“昂贵”的数组操作来提高效率。
奖金编辑:另一种可能性是使用 发电机(假设你有 支持):
然后使用:
其中
ranNums.next().value
最终将评估为undefined
一旦你运行了随机数组中的所有元素。总体而言,这不会像 Fisher–Yates Shuffle 那样高效,因为您仍然是
splice
数组。但不同之处在于,您现在只在需要时才做这项工作,而不是提前完成所有工作,因此根据您的用例,这可能会更好。