我怎样才能制作一个没有重复的随机数组?
How can I make a random array with no repeats?
我一直在寻找这个问题的一些答案,但当我试图找到解决方案时似乎没有任何效果。
我想要实现的是在 Javascript 和 Adobe Edge 中制作一个旋转器,随机旋转一个数字,确实在旋转所有数字之前,不要再次重复该数字。
我知道这对于一个体面的编码员来说应该很容易做到,但我还没有那么有经验。
这是我目前所拥有的,但它是未完成的并且有错误:
var myArray = ['360', '330', '300', '270', '240', '210', '180', '150', '120', '90', '60', '30'];
var Spinner1 = sym.$('Spinner1');
Spinner1.click(function(){
// randomize the degree of spin.
var mySpin = myArray[Math.floor(Math.random() * myArray.length)];
sym.getSymbol('Spinner1').play();
Spinner1.css({
'-webkit-transform': 'rotate(' + mySpin + 'deg)',
'-moz-transform': 'rotate(' + mySpin + 'deg)',
'-ms-transform': 'rotate(' + mySpin + 'deg)',
'-o-transform': 'rotate(' + mySpin + 'deg)',
'transform': 'rotate(' + mySpin + 'deg)',
});
Spinner1.css('-webkit-transition','all 500ms cubic-bezier(0.420, 0.000, 1.000, 1.000)');
if (mySpin > 300 && mySpin < 360) {
alert("Winner is number 1!");
}
});
希望有人能帮助我。提前致谢。
您可以通过两种方式实现这一目标。
存储一组已经旋转的值。然后,当您生成一个新数字时,检查它是否在旋转数字数组中。如果是,则生成一个新数字并再次检查,直到得到一个不在数组中的数字。否则,将其添加到数组中。
像您一样预先生成一个包含所有有效数字的数组。然后,每次旋转一个数字时,将其从该数组中删除。这样,下次您 'spin' 时,您将只 select 从尚未旋转的值中获取。
预先生成所有有效数字的数组,然后随机排序。然后你所要做的就是继续取数组中的第一项。
按顺序,选项 3. 是最优雅的,但它的缺点是打开控制台的人可能会准确地看到下一个数字!选项 2 次之,如果允许用户知道一个号码不能出现两次,他们就无法 'cheat' 通过查看剩余的可用号码。选项 1 效率最低 - 因为这意味着您的代码将需要做越来越多的工作来尝试找到 'free' 数字。
老实说,如果您的游戏需要完全免受黑客攻击,那么无论如何您都不想在客户端生成任何随机数,所以如果这只是为了一点乐趣,那也无所谓你使用哪种方法。如果你是为博彩网站写的,先告诉我是哪一个,这样我就可以发财了,然后把你的逻辑移到服务器上。
所以这是选项 2 的示例。方法
<!DOCTYPE html>
<html>
<head>
<script>
var numbers = []; // this array will store the available numbers..
function generateNumbers()
{
// populate the available numbers however you need to..
for(var i=0; i<360; i+=30)
{
numbers.push(i);
}
}
function spin()
{
if(numbers.length==0)
{
// then we've used up all available numbers..start new game or whatever you need to do..
alert("starting again");
generateNumbers();
}
var rand = Math.floor(Math.random()*numbers.length); // select an index randomly based on the number of remaining available numbers..
var num = numbers[rand];
numbers.splice(rand,1); // remove the number we selected so it can't be selected next time..
document.getElementById("number").innerHTML = num;
}
</script>
</head>
<body>
<button onclick="spin()">SPIN</button>
<div id="number"></div>
</body>
</html>
和下面的选项 3。主要区别在于您可以直接 shift() 下一个值,而不必随机 select 。
<!DOCTYPE html>
<html>
<head>
<script>
var numbers = [];
function generateNumbers()
{
for(var i=0; i<360; i+=30)
{
numbers.push(i);
}
function sort(a,b)
{
return (Math.random()>0.5)? -1 : 1;
}
numbers.sort(sort);
}
function spin()
{
if(numbers.length==0)
{
alert("starting again");
generateNumbers();
}
var num = numbers.shift();
document.getElementById("available").innerHTML = "Available:" + numbers.join(",");
document.getElementById("number").innerHTML = "Selected:" + num;
}
</script>
</head>
<body>
<button onclick="spin()">SPIN</button>
<div id="available"></div>
<div id="number"></div>
</body>
</html>
希望这能让您了解如何将其合并到您的代码中。
您似乎已经有了一组可能的值。在这种情况下,您可以简单地打乱数组并遍历它。 JavaScript 没有内置随机播放功能,但实现起来非常简单。
这是一个 Fisher–Yates shuffle
的例子
function shuffle(array) {
for(var i = array.length; i > 1; i--) {
var r = Math.floor(Math.random() * i);
var temp = array[r];
array[r] = array[i-1];
array[i-1] = temp;
}
}
你需要做的是,选择一个随机数并将其存储在数组中,但在你存储它之前,检查它是否已经存在于该数组,如果存在,则选择另一个。
如果您选择的值数组包含所有可能的值,则重置数组。
示例如下:https://jsfiddle.net/5a7mqsbn/1/
var alreadyArr = new Array();
$(function() {
$("#generate").click(function() {
var newFound = false;
do {
var num = (Math.floor(Math.random() * 12) + 1) * 30;
if (alreadyArr.length == 12) {
alreadyArr = [num];
newFound = true;
} else if (alreadyArr.indexOf(num) < 0) {
alreadyArr.push(num);
newFound = true;
}
} while (!newFound);
$("#numbers").text(alreadyArr);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<p id="numbers"></p>
<button id="generate">
Next Random number
</button>
此函数将使用Math.random()
随机选择数组中的一个数字,直到所有数字都被使用后才再次选择它:
var originalArray = ['360', '330', '300', '270', '240', '210',
'180', '150', '120', '90', '60', '30'];
var totalSpin = [];
function spinArray(){
var spin = Math.floor(Math.random()*originalArray.length);
if(totalSpin.indexOf(spin) == -1){
totalSpin.push(spin);
parag.innerHTML = originalArray[spin];
} else {
spinArray();
}
if(totalSpin.length == originalArray.length)
totalSpin = [];
}
这是fiddle:https://jsfiddle.net/628yqz0v/4/
var array = [];
setInterval(function(){
if(array .length === 0){
reload();
}
var result = getRandom();
console.log(result);
},1000);
function getRandom(){
var index = (array.length === 1 ? 0 : Math.floor(Math.random() * array.length));
return array.splice(index, 1)[0];
}
function reload(){
array = [2,3,4,5,6,7,8,9,0,1,44,66];
}
鉴于您已经拥有数组值并且您需要 randomize
它们的位置这一事实,您可以采取另一种方法是生成 unique random values
和 Set:
var data = ['360', '330', '300', '270', '240', '210','180', '150', '120', '90', '60', '30'];
let getUniqueRandomNumbers = n => {
let set = new Set()
while (set.size < n) set.add(Math.floor(Math.random() * n))
return Array.from(set)
}
let result = getUniqueRandomNumbers(data.length).map(x => data[x])
console.log(result)
想法是生成新数组的索引,然后使用这些索引通过 Array.map
填充它。
您可以采用的另一种方法是通过 Array.sort
和 Math.random
:
var data = ['360', '330', '300', '270', '240', '210','180', '150', '120', '90', '60', '30'];
let result = data.sort(function(a, b){
return 0.5 - Math.random() // <— sort needs a number and this makes it work
});
console.log(result);
我一直在寻找这个问题的一些答案,但当我试图找到解决方案时似乎没有任何效果。
我想要实现的是在 Javascript 和 Adobe Edge 中制作一个旋转器,随机旋转一个数字,确实在旋转所有数字之前,不要再次重复该数字。
我知道这对于一个体面的编码员来说应该很容易做到,但我还没有那么有经验。
这是我目前所拥有的,但它是未完成的并且有错误:
var myArray = ['360', '330', '300', '270', '240', '210', '180', '150', '120', '90', '60', '30'];
var Spinner1 = sym.$('Spinner1');
Spinner1.click(function(){
// randomize the degree of spin.
var mySpin = myArray[Math.floor(Math.random() * myArray.length)];
sym.getSymbol('Spinner1').play();
Spinner1.css({
'-webkit-transform': 'rotate(' + mySpin + 'deg)',
'-moz-transform': 'rotate(' + mySpin + 'deg)',
'-ms-transform': 'rotate(' + mySpin + 'deg)',
'-o-transform': 'rotate(' + mySpin + 'deg)',
'transform': 'rotate(' + mySpin + 'deg)',
});
Spinner1.css('-webkit-transition','all 500ms cubic-bezier(0.420, 0.000, 1.000, 1.000)');
if (mySpin > 300 && mySpin < 360) {
alert("Winner is number 1!");
}
});
希望有人能帮助我。提前致谢。
您可以通过两种方式实现这一目标。
存储一组已经旋转的值。然后,当您生成一个新数字时,检查它是否在旋转数字数组中。如果是,则生成一个新数字并再次检查,直到得到一个不在数组中的数字。否则,将其添加到数组中。
像您一样预先生成一个包含所有有效数字的数组。然后,每次旋转一个数字时,将其从该数组中删除。这样,下次您 'spin' 时,您将只 select 从尚未旋转的值中获取。
预先生成所有有效数字的数组,然后随机排序。然后你所要做的就是继续取数组中的第一项。
按顺序,选项 3. 是最优雅的,但它的缺点是打开控制台的人可能会准确地看到下一个数字!选项 2 次之,如果允许用户知道一个号码不能出现两次,他们就无法 'cheat' 通过查看剩余的可用号码。选项 1 效率最低 - 因为这意味着您的代码将需要做越来越多的工作来尝试找到 'free' 数字。
老实说,如果您的游戏需要完全免受黑客攻击,那么无论如何您都不想在客户端生成任何随机数,所以如果这只是为了一点乐趣,那也无所谓你使用哪种方法。如果你是为博彩网站写的,先告诉我是哪一个,这样我就可以发财了,然后把你的逻辑移到服务器上。
所以这是选项 2 的示例。方法
<!DOCTYPE html>
<html>
<head>
<script>
var numbers = []; // this array will store the available numbers..
function generateNumbers()
{
// populate the available numbers however you need to..
for(var i=0; i<360; i+=30)
{
numbers.push(i);
}
}
function spin()
{
if(numbers.length==0)
{
// then we've used up all available numbers..start new game or whatever you need to do..
alert("starting again");
generateNumbers();
}
var rand = Math.floor(Math.random()*numbers.length); // select an index randomly based on the number of remaining available numbers..
var num = numbers[rand];
numbers.splice(rand,1); // remove the number we selected so it can't be selected next time..
document.getElementById("number").innerHTML = num;
}
</script>
</head>
<body>
<button onclick="spin()">SPIN</button>
<div id="number"></div>
</body>
</html>
和下面的选项 3。主要区别在于您可以直接 shift() 下一个值,而不必随机 select 。
<!DOCTYPE html>
<html>
<head>
<script>
var numbers = [];
function generateNumbers()
{
for(var i=0; i<360; i+=30)
{
numbers.push(i);
}
function sort(a,b)
{
return (Math.random()>0.5)? -1 : 1;
}
numbers.sort(sort);
}
function spin()
{
if(numbers.length==0)
{
alert("starting again");
generateNumbers();
}
var num = numbers.shift();
document.getElementById("available").innerHTML = "Available:" + numbers.join(",");
document.getElementById("number").innerHTML = "Selected:" + num;
}
</script>
</head>
<body>
<button onclick="spin()">SPIN</button>
<div id="available"></div>
<div id="number"></div>
</body>
</html>
希望这能让您了解如何将其合并到您的代码中。
您似乎已经有了一组可能的值。在这种情况下,您可以简单地打乱数组并遍历它。 JavaScript 没有内置随机播放功能,但实现起来非常简单。
这是一个 Fisher–Yates shuffle
的例子function shuffle(array) {
for(var i = array.length; i > 1; i--) {
var r = Math.floor(Math.random() * i);
var temp = array[r];
array[r] = array[i-1];
array[i-1] = temp;
}
}
你需要做的是,选择一个随机数并将其存储在数组中,但在你存储它之前,检查它是否已经存在于该数组,如果存在,则选择另一个。 如果您选择的值数组包含所有可能的值,则重置数组。
示例如下:https://jsfiddle.net/5a7mqsbn/1/
var alreadyArr = new Array();
$(function() {
$("#generate").click(function() {
var newFound = false;
do {
var num = (Math.floor(Math.random() * 12) + 1) * 30;
if (alreadyArr.length == 12) {
alreadyArr = [num];
newFound = true;
} else if (alreadyArr.indexOf(num) < 0) {
alreadyArr.push(num);
newFound = true;
}
} while (!newFound);
$("#numbers").text(alreadyArr);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<p id="numbers"></p>
<button id="generate">
Next Random number
</button>
此函数将使用Math.random()
随机选择数组中的一个数字,直到所有数字都被使用后才再次选择它:
var originalArray = ['360', '330', '300', '270', '240', '210',
'180', '150', '120', '90', '60', '30'];
var totalSpin = [];
function spinArray(){
var spin = Math.floor(Math.random()*originalArray.length);
if(totalSpin.indexOf(spin) == -1){
totalSpin.push(spin);
parag.innerHTML = originalArray[spin];
} else {
spinArray();
}
if(totalSpin.length == originalArray.length)
totalSpin = [];
}
这是fiddle:https://jsfiddle.net/628yqz0v/4/
var array = [];
setInterval(function(){
if(array .length === 0){
reload();
}
var result = getRandom();
console.log(result);
},1000);
function getRandom(){
var index = (array.length === 1 ? 0 : Math.floor(Math.random() * array.length));
return array.splice(index, 1)[0];
}
function reload(){
array = [2,3,4,5,6,7,8,9,0,1,44,66];
}
鉴于您已经拥有数组值并且您需要 randomize
它们的位置这一事实,您可以采取另一种方法是生成 unique random values
和 Set:
var data = ['360', '330', '300', '270', '240', '210','180', '150', '120', '90', '60', '30'];
let getUniqueRandomNumbers = n => {
let set = new Set()
while (set.size < n) set.add(Math.floor(Math.random() * n))
return Array.from(set)
}
let result = getUniqueRandomNumbers(data.length).map(x => data[x])
console.log(result)
想法是生成新数组的索引,然后使用这些索引通过 Array.map
填充它。
您可以采用的另一种方法是通过 Array.sort
和 Math.random
:
var data = ['360', '330', '300', '270', '240', '210','180', '150', '120', '90', '60', '30'];
let result = data.sort(function(a, b){
return 0.5 - Math.random() // <— sort needs a number and this makes it work
});
console.log(result);