【问题标题】:How do I make javascript display random names without repeats?如何让 javascript 显示随机名称而不重复?
【发布时间】:2016-03-30 18:25:35
【问题描述】:

我需要能够单击一个按钮,然后以随机顺序出现几个不同的名称,而不会重复任何名称。显示随机名称很简单,但我无法避免重复。这就是我所拥有的,但我不明白为什么它不起作用。

<script>

var players = []
players[0] = "Billy";
players[1] = "Alex";
players[2] = "Kevin";
players[3] = "Fred";

function tournament(amount) {
    var a = 0, i = 0, place = 1;
    randomlyselect:
    while (a<amount) {
        var randomplayer = Math.floor(Math.random()*(players.length));
        if (players[randomplayer] === document.getElementById('player1').innerHTML || document.getElementById('player2').innerHTML || document.getElementById('player3').innerHTML) {
            continue randomlyselect;
            } 
        else {
            document.getElementById('player'+place).innerHTML = players[randomplayer];
            place++;
            a++;
        }
    }

}

</script>

<button onClick="tournament(4)">Tournament Results</button>

<p id="player1"></p>
<p id="player2"></p>
<p id="player3"></p>
<p id="player4"></p>

我知道问题在于 if 语句,但我不知道如何检查名称是否已显示。如果您知道我检查某些东西是否已经被挑选的方法有什么问题,或者是避免重复的更好方法,请告诉我。

【问题讨论】:

    标签: javascript html arrays loops random


    【解决方案1】:

    这是一个通用函数方法,用于创建一个新数组,其中原始数组的值以随机顺序而不重复:

    function randomizeArrayValues(arr) {
        return String(Array(arr.length))
               .split(',')
               .map(
                  function () {
                    return this
                           .splice(Math.floor((Math.random()*this.length)), 1)
                           .pop();
                  }, 
                  arr.slice()
        );
    }
    
    // example
    // -------
    var players = ["Billy", "Alex", "Kevin", "Fred", "Mary", "Beth"];
    var trial = 10;
    
    while (trial--) {
     document.querySelector('#result').textContent += 
          randomizeArrayValues(players).join(', ') + '\n';
    }
    &lt;pre id="result"&gt;&lt;/pre&gt;

    【讨论】:

      【解决方案2】:

      您可以克隆原始数组,然后将其中的项目一一拼接。这样,您将保证每次都能获得独特的结果。

      var players = ["Billy", "Alex", "Kevin", "Fred"];
      
      function tournament(amount) {
        
          var clone = players.slice(), i, player;
      
          for (var i = 0; i < amount; i++) {
              player = clone.splice(Math.floor(Math.random() * clone.length), 1);
              document.getElementById('player' + (i + 1)).innerHTML = player;
          }
      }
      <button onClick="tournament(4)">Tournament Results</button>
      
      <p id="player1"></p>
      <p id="player2"></p>
      <p id="player3"></p>
      <p id="player4"></p>

      但请注意,由于它会创建数组的副本,因此这种方法在玩家数组非常大的情况下可能并不理想。

      【讨论】:

        【解决方案3】:

        我会从数组中切出每个选择,这样就无法再次选择它,然后将其写入循环中。

        var randomplayer = Math.floor(Math.random()*(players.length));
        players = players.slice(randomplayer, 1);
        

        编辑:让我编写整个函数以防万一出现混乱。

        function tournament(){
            var place = 1;
            while(players.length > 0){
                var randomplayer = Math.floor(Math.random()*(players.length));
                document.getElementById('player'+place).innerHTML = players[randomplayer];
                players = players.slice(randomplayer, 1);
                place++;
            }
        }
        

        【讨论】:

        • 你可以这样做,但如果 OP 想再次使用数组,他必须先复制数组或做各种丑陋的事情。
        • 由于复制数组就像players.slice(0) 一样简单,我无法想象这是一个问题。
        • 老实说,这只是一个书呆子的意见,复制您的数据而您的功能并不表明它是令人讨厌的。这意味着大型项目的性能问题,尽管我打赌对于 OPs 问题,这可能是更少的工作。
        • 我想这取决于 OP 是否需要保留数组,对吧?
        • 是的,考虑到这一点,目前或未来的 OPs 项目都是可能的,最好编写不会带来副作用的代码,而不是会带来副作用的代码。
        【解决方案4】:

        var players = []
        players[0] = "Billy";
        players[1] = "Alex";
        players[2] = "Kevin";
        players[3] = "Fred";
        
        
        function tournament(amount) {
          var randomOrder = shuffle(players)
          var count = Math.min(amount, randomOrder.length)
          for (var i = 0; i < count; ++i) {
            document.getElementById("player" + (i + 1)).textContent = randomOrder[i]
          }
        }
        
        // http://stackoverflow.com/a/2450976/4339170
        function shuffle(array) {
          var currentIndex = array.length,
            temporaryValue, randomIndex;
        
          // While there remain elements to shuffle...
          while (0 !== currentIndex) {
        
            // Pick a remaining element...
            randomIndex = Math.floor(Math.random() * currentIndex);
            currentIndex -= 1;
        
            // And swap it with the current element.
            temporaryValue = array[currentIndex];
            array[currentIndex] = array[randomIndex];
            array[randomIndex] = temporaryValue;
          }
        
          return array;
        }
        <button onClick="tournament(4)">Tournament Results</button>
        
        <p id="player1"></p>
        <p id="player2"></p>
        <p id="player3"></p>
        <p id="player4"></p>

        【讨论】:

        • 这是最好的方法,因为小算法(被证明运行良好),您可以获得非常好的随机性。您还可以保持数组完好无损,这样您就可以在同一个页面加载中多次使用它,同时确保不会有重复的名称
        • @HalfEmptyJar 如果您需要有关代码的任何帮助或解释,请在 cmets 中询问
        • 你为什么使用 "Math.min(amount, randomOrder.length)" 而不是仅仅使用数量。为什么你使用 textContent 而不是 innerHTML?
        • @HalfEmptyJar Math.min(amount, randomOrder.length) 以防数组小于数量。 TextContet,你也可以使用innerHTML
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-04-03
        相关资源
        最近更新 更多