防止随后的随机结果在Javascript中重复

Prevent Subsequent Random Results Repeating In Javascript

本文关键字:Javascript 结果 随机      更新时间:2023-09-26

在我的网站上,我有一个按钮,从报价列表中选择随机报价,并将随机选择的报价投影到文本框中。这是使用JavaScript完成的。

虽然我有这个工作,我想要一个额外的代码片段,将防止直接随后的报价与前一个相同。我希望任何引用都能再次出现,但是,只是不要直接出现在后面。

如果可能的话,我也希望它这样使用的任何报价不会再次出现至少另外3次点击-但这只是一个奖励。

无论如何,我目前的代码如下:

<head>    
  <script language="javascript"><!--
    function GenerateQuote(){var aquote=new Array;
      aquote[0]="'"Quote0'"";
      aquote[1]="'"Quote1'"";
      aquote[2]="'"Quote2'""
      aquote[3]="'"Quote3'"";
      aquote[4]="'"Quote4'"";
      aquote[5]="'"Quote5'"";
      aquote[6]="'"Quote6'"";
    rdmQuote=Math.floor(Math.random()*aquote.length);
    document.getElementById("quoteBox").value=aquote[rdmQuote];
    }
  -->
  </script>
</head>
<body>
  <textarea id="quoteBox" readonly></textarea>
  <button onClick="GenerateQuote()">Entertainment & Hobbies</button>
</body>

提前感谢;我相信这对你们这些笨蛋来说不会太难的!

  1. 填充一个引号数组,然后创建一个副本
  2. 打乱数组的副本(你可以只使用.sort()方法,甚至更好,你可以寻找一个js实现的Fisher-Yates算法
  3. 在每次点击事件时调用数组上的pop(),这样您将每次生成不同的报价,直到数组完全消耗
  4. 当数组长度为0时,返回到1)
参考:

  • http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle
  • https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/sort
  • https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/pop
<head>
    <script type="text/javascript">
!function (){
    var quotes = ["quote0", "quote1", "quote2", "quote3", "quote4", "quote5", "quote6", "quote7", "quote8"],
        shuffleAfter = quotes.length, cur = 0;

    function shuffle( arr ) {
        var l = arr.length, j, i, tmp;
        for( i = l - 1; i > 0; --i ) {
            j = ( Math.random() * ( i + 1 ) ) >>> 0;
            tmp = arr[i];
            arr[i] = arr[j];
            arr[j] = tmp;
        }
        return arr;
    }
    function generateQuote(){
        var r;
        if( cur++ % shuffleAfter === 0 ) {
            shuffle(quotes);
        }
        r = quotes.shift();
        quotes.push( r );
        return r;
    }

    window.generateQuote = generateQuote;
}()
    </script>
</head>
<body>
    <textarea id="quoteBox" readonly></textarea>
    <button onClick="document.getElementById('quoteBox').value = generateQuote()">Entertainment & Hobbies</button>
</body>

调用generateQuote() 27次结果:

2,9,7,5,8,1,3,4,6,9,6,1,7,5,4,3,2,8,3,1,6,5,2,7,9,4,8,2

正如你所看到的,在一个完整的循环之后,引号再次被洗牌,如果相同的引号在上一个周期中是最后一个,并且在新周期中是第一个,则有可能出现相同的引号。它至少比我mp3播放器里的播放列表变换要好得多:P

use

var lastQuote=-1;

在函数外,然后

var rdmQuote=lastQuote;
while (rdmQuote==lastQUote) rdmQuote=Math.floor(Math.random()*aquote.length);
lastQuote=rdmQuote;

你可以调整dontRepeatUntil来满足你的需要当然有更好的方法,但是这个应该可以

var latestQuote = []
    , dontRepeatUntil=3
    , rdmQuote = null
    , quotes=[
        "'"Quote0'""
        ,"'"Quote2'""
        ,"'"Quote3'""
        ,"'"Quote4'""
        ,"'"Quote5'""
        ,"'"Quote6'""
    ]
;
function GenerateQuote(){
if(latestQuote.length >= dontRepeatUntil){
    latestQuote = latestQuote.slice(latestQuote.length-dontRepeatUntil+1);
}
    do{
        rdmQuote=Math.floor(Math.random()*quotes.length);
    }while(latestQuote.join(',').match(new RegExp('(^|,)'+rdmQuote+'(,|$)')));
    latestQuote.push(rdmQuote);
    document.getElementById("quoteBox").value=quotes[rdmQuote];
}