我怎样才能制作一个没有重复的随机数组?

How can I make a random array with no repeats?

我一直在寻找这个问题的一些答案,但当我试图找到解决方案时似乎没有任何效果。

我想要实现的是在 Javascript 和 Adob​​e 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!");
   }
});

希望有人能帮助我。提前致谢。

您可以通过两种方式实现这一目标。

  1. 存储一组已经旋转的值。然后,当您生成一个新数字时,检查它是否在旋转数字数组中。如果是,则生成一个新数字并再次检查,直到得到一个不在数组中的数字。否则,将其添加到数组中。

  2. 像您一样预先生成一个包含所有有效数字的数组。然后,每次旋转一个数字时,将其从该数组中删除。这样,下次您 'spin' 时,您将只 select 从尚未旋转的值中获取。

  3. 预先生成所有有效数字的数组,然后随机排序。然后你所要做的就是继续取数组中的第一项。

按顺序,选项 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 valuesSet:

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.sortMath.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);