Javascript 生成 1 到 100 之间的唯一随机数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2380019/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Generate unique random numbers between 1 and 100
提问by dotty
How can I generate some unique randomnumbers between 1 and 100 using JavaScript?
如何使用 JavaScript生成1 到 100 之间的一些唯一随机数?
回答by adam0101
For example: To generate 8 unique random numbers and store them to an array, you can simply do this:
例如:要生成 8 个唯一的随机数并将它们存储到一个数组中,您可以简单地执行以下操作:
var arr = [];
while(arr.length < 8){
var r = Math.floor(Math.random() * 100) + 1;
if(arr.indexOf(r) === -1) arr.push(r);
}
console.log(arr);
回答by ЯegDwight
- Populate an array with the numbers 1 through 100.
- Shuffle it.
- Take the first 8 elements of the resulting array.
- 用数字 1 到 100 填充数组。
- 洗牌吧。
- 取结果数组的前 8 个元素。
回答by Pratik Deoghare
Generate permutationof 100 numbers and then choose serially.
生成100 个数字的排列,然后依次选择。
Use Knuth Shuffle(aka the Fisher-Yates shuffle) Algorithm.
使用Knuth Shuffle(又名 Fisher-Yates shuffle)算法。
JavaScript:
JavaScript:
function fisherYates ( myArray,stop_count ) {
var i = myArray.length;
if ( i == 0 ) return false;
int c = 0;
while ( --i ) {
var j = Math.floor( Math.random() * ( i + 1 ) );
var tempi = myArray[i];
var tempj = myArray[j];
myArray[i] = tempj;
myArray[j] = tempi;
// Edited thanks to Frerich Raabe
c++;
if(c == stop_count)return;
}
}
EDIT:
编辑:
Improved code:
改进的代码:
function fisherYates(myArray,nb_picks)
{
for (i = myArray.length-1; i > 1 ; i--)
{
var r = Math.floor(Math.random()*i);
var t = myArray[i];
myArray[i] = myArray[r];
myArray[r] = t;
}
return myArray.slice(0,nb_picks);
}
Potential problem:
潜在问题:
Suppose we have array of 100 numbers {e.g. [1,2,3...100]} and we stop swapping after 8 swaps; then most of the times array will look like {1,2,3,76,5,6,7,8,...numbers here will be shuffled ...10}.
假设我们有 100 个数字的数组 {例如 [1,2,3...100]},并且我们在 8 次交换后停止交换;那么大多数时间数组看起来像 {1,2,3,76,5,6,7,8,...这里的数字将被洗牌...10}。
Because every number will be swapped with probability 1/100 so prob. of swapping first 8 numbers is 8/100 whereas prob. of swapping other 92 is 92/100.
因为每个数字都会以 1/100 的概率交换所以概率。交换前 8 个数字是 8/100 而概率。交换其他 92 是 92/100。
But if we run algorithm for full array then we are sure (almost)every entry is swapped.
但是,如果我们为完整数组运行算法,那么我们可以确定(几乎)每个条目都被交换。
Otherwise we face a question : which 8 numbers to choose?
否则我们就会面临一个问题:选择哪8个号码?
回答by Alister
回答by Victor Quinn
The above techniques are good if you want to avoid a library, but depending if you would be alright with a library, I would suggest checking out Chancefor generating random stuff in JavaScript.
如果您想避免使用库,上述技术是很好的,但取决于您是否适合使用库,我建议您查看Chance以在 JavaScript 中生成随机内容。
Specifically to solve your question, using Chance it's as easy as:
特别是为了解决您的问题,使用 Chance 就像这样简单:
// One line!
var uniques = chance.unique(chance.natural, 8, {min: 1, max: 100});
// Print it out to the document for this snippet so we can see it in action
document.write(JSON.stringify(uniques));
<script src="http://chancejs.com/chance.min.js"></script>
Disclaimer, as the author of Chance, I am a bit biased ;)
免责声明,作为 Chance 的作者,我有点偏见 ;)
回答by belugabob
To avoid any long and unreliable shuffles, I'd do the following...
为了避免任何长时间和不可靠的洗牌,我会做以下...
- Generate an array that contains the number between 1 and 100, in order.
- Generate a random number between 1 and 100
- Look up the number at this index in the array and store in your results
- Remove the elemnt from the array, making it one shorter
- Repeat from step 2, but use 99 as the upper limit of the random number
- Repeat from step 2, but use 98 as the upper limit of the random number
- Repeat from step 2, but use 97 as the upper limit of the random number
- Repeat from step 2, but use 96 as the upper limit of the random number
- Repeat from step 2, but use 95 as the upper limit of the random number
- Repeat from step 2, but use 94 as the upper limit of the random number
- Repeat from step 2, but use 93 as the upper limit of the random number
- 按顺序生成一个包含 1 到 100 之间数字的数组。
- 生成 1 到 100 之间的随机数
- 在数组中查找此索引处的数字并将其存储在结果中
- 从数组中删除元素,使其更短
- 从第 2 步开始重复,但使用 99 作为随机数的上限
- 从第 2 步开始重复,但使用 98 作为随机数的上限
- 从第 2 步开始重复,但使用 97 作为随机数的上限
- 从第 2 步开始重复,但使用 96 作为随机数的上限
- 从第 2 步开始重复,但使用 95 作为随机数的上限
- 从第 2 步开始重复,但使用 94 作为随机数的上限
- 从第 2 步开始重复,但使用 93 作为随机数的上限
Voila - no repeated numbers.
瞧 - 没有重复的数字。
I may post some actual code later, if anybody is interested.
如果有人感兴趣,我可能会稍后发布一些实际代码。
Edit: It's probably the competitive streak in me but, having seen the post by @Alsciende, I couldn't resist posting the code that I promised.
编辑:这可能是我的连续竞争,但是看到@Alsciende 的帖子后,我忍不住发布了我承诺的代码。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<html>
<head>
<title>8 unique random number between 1 and 100</title>
<script type="text/javascript" language="Javascript">
function pick(n, min, max){
var values = [], i = max;
while(i >= min) values.push(i--);
var results = [];
var maxIndex = max;
for(i=1; i <= n; i++){
maxIndex--;
var index = Math.floor(maxIndex * Math.random());
results.push(values[index]);
values[index] = values[maxIndex];
}
return results;
}
function go(){
var running = true;
do{
if(!confirm(pick(8, 1, 100).sort(function(a,b){return a - b;}))){
running = false;
}
}while(running)
}
</script>
</head>
<body>
<h1>8 unique random number between 1 and 100</h1>
<p><button onclick="go()">Click me</button> to start generating numbers.</p>
<p>When the numbers appear, click OK to generate another set, or Cancel to stop.</p>
</body>
回答by Felix Lemke
Another approach is to generate an 100 items array with ascending numbers and sort it randomly. This leads actually to a really short and (in my opinion) simple snippet.
另一种方法是生成一个 100 项的数组,并随机排序。这实际上导致了一个非常短且(在我看来)简单的片段。
const numbers = Array(100).fill().map((_, index) => index + 1);
numbers.sort(() => Math.random() - 0.5);
console.log(numbers.slice(0, 8));
回答by kaizer1v
This is a very generic function I have written to generate random unique/non-unique integers for an array. Assume the last parameter to be true in this scenario for this answer.
这是我编写的一个非常通用的函数,用于为数组生成随机的唯一/非唯一整数。假设此答案的最后一个参数在此场景中为真。
/* Creates an array of random integers between the range specified
len = length of the array you want to generate
min = min value you require
max = max value you require
unique = whether you want unique or not (assume 'true' for this answer)
*/
function _arrayRandom(len, min, max, unique) {
var len = (len) ? len : 10,
min = (min !== undefined) ? min : 1,
max = (max !== undefined) ? max : 100,
unique = (unique) ? unique : false,
toReturn = [], tempObj = {}, i = 0;
if(unique === true) {
for(; i < len; i++) {
var randomInt = Math.floor(Math.random() * ((max - min) + min));
if(tempObj['key_'+ randomInt] === undefined) {
tempObj['key_'+ randomInt] = randomInt;
toReturn.push(randomInt);
} else {
i--;
}
}
} else {
for(; i < len; i++) {
toReturn.push(Math.floor(Math.random() * ((max - min) + min)));
}
}
return toReturn;
}
Here the 'tempObj' is a very useful obj since every random number generated will directly check in this tempObj if that key already exists, if not, then we reduce the i by one since we need 1 extra run since the current random number already exists.
这里'tempObj'是一个非常有用的obj,因为如果该键已经存在,生成的每个随机数都会直接检查这个tempObj,如果不存在,那么我们将i减一,因为我们需要1次额外运行,因为当前随机数已经存在.
In your case, run the following
在您的情况下,请运行以下命令
_arrayRandom(8, 1, 100, true);
That's all.
就这样。
回答by Gumbo
I would do this:
我会这样做:
function randomInt(min, max) {
return Math.round(min + Math.random()*(max-min));
}
var index = {}, numbers = [];
for (var i=0; i<8; ++i) {
var number;
do {
number = randomInt(1, 100);
} while (index.hasOwnProperty("_"+number));
index["_"+number] = true;
numbers.push(number);
}
delete index;
回答by Randal Schwartz
Shuffling the numbers from 1 to 100 is the right basic strategy, but if you need only 8 shuffled numbers, there's no need to shuffle all 100 numbers.
将数字从 1 打乱到 100 是正确的基本策略,但如果您只需要 8 个打乱的数字,则无需打乱所有 100 个数字。
I don't know Javascript very well, but I believe it's easy to create an array of 100 nulls quickly. Then, for 8 rounds, you swap the n'th element of the array (n starting at 0) with a randomly selected element from n+1 through 99. Of course, any elements not populated yet mean that the element would really have been the original index plus 1, so that's trivial to factor in. When you're done with the 8 rounds, the first 8 elements of your array will have your 8 shuffled numbers.
我不太了解 Javascript,但我相信快速创建一个包含 100 个空值的数组很容易。然后,在 8 轮中,您将数组的第 n 个元素(n 从 0 开始)与从 n+1 到 99 中随机选择的元素交换。当然,任何尚未填充的元素都意味着该元素实际上已经原始索引加 1,因此无需考虑。当您完成 8 轮后,数组的前 8 个元素将包含您的 8 个混洗数字。

