Javascript 如何随机浏览未知数量的引号而不重复

Javascript 如何随机浏览未知数量的引号而不重复,javascript,Javascript,我有一个Javascript的小片段,我在其中按照从头到尾的顺序循环引用列表 但是,我希望随机地遍历列表(而不是按顺序),在所有引号都被遍历之前不重复,然后再次以随机引号开始。我该怎么做呢 $(function(){ var quotes = $('#quotes').children('.rotate-quote'); firstQuo = quotes.filter(':first'); lastQuo = quotes.filter(':last'); qu

我有一个Javascript的小片段,我在其中按照从头到尾的顺序循环引用列表

但是,我希望随机地遍历列表(而不是按顺序),在所有引号都被遍历之前不重复,然后再次以随机引号开始。我该怎么做呢

$(function(){
    var quotes = $('#quotes').children('.rotate-quote');
    firstQuo = quotes.filter(':first');
    lastQuo = quotes.filter(':last');
    quotes.first().show();
    setInterval(function(){
        if($(lastQuo).is(':visible')) {
            var nextElem = $(firstQuo);
        } else {
            var nextElem = $(quotes).filter(':visible').next();
        }
        $(quotes).filter(':visible').fadeOut(300);
        if($(lastQuo).is(':visible')) {
            setTimeout(function() {
                $(firstQuo).fadeIn(300);
            }, 600);

        } else {
            setTimeout(function() {
                $(nextElem).fadeIn(600);
            }, 600);
        }
    }, 10000);
});

只是为了展示Fisher Yates(不是我的代码):


因此,将您的引号放入一个数组,通过该函数运行它,然后在数组中循环,当您到达末尾时,再次通过该函数运行它,等等。

下面是一个可能的演示解决方案:

var $container = $('div'),
    quotes = $('quote').hide().toArray(),
    delay = 500;

function shuffle(arr) {
  return arr.map(function(v){ return [v,Math.random()]; })
    .sort().map(function(v){ return v[0]; });
}

function loop() {
  $(shuffle(quotes)).each(function(i,el) {
    setTimeout(function(){ $(el).appendTo($container).show(); }, i*delay);
  });
}

function start() {
  function begin(){ $(quotes).hide(); loop(); }
  setInterval(begin, quotes.length * delay);
  begin();
}

start();
演示:


编辑:我把它变成了一个小插件,在这里抓取它

下面复制quote数组,然后每次随机从中分割一个。wWen没有剩余条目,它将再次启动

var randomQuote = (function() {
  var quotes = ['quote 0','quote 1','quote 2'];
  var quoteCopy = [];

  return function () {
    if (!quoteCopy.length) {
      quoteCopy = quotes.slice();
    }
    return quoteCopy.splice(Math.random()*quoteCopy.length | 0, 1)[0];
  }
}());

我认为你所说的算法不好。假设您有100个引号,然后您对整个集合进行第一次随机演示

最后,正如您在描述中所述,将从头开始,因此101号报价可能与100号报价相同

我认为更好(更统一)的东西会更好

  • 随机洗牌
    n
    引号。这在开始时只做一次
  • 选择第一个报价并显示它
  • 从列表中删除引号,并将其插入
    n-w
    n
    之间的随机位置,其中
    w
    是一个参数(例如
    n/2
  • 对您需要的每个报价重复第2步
  • 数字
    w
    将调节序列的随机性。。。报价提交后,延迟越小,越均匀


    使用这种方法,将不会出现“分发故障”,并且下次提交报价后的平均延迟将不取决于当前位置。

    您似乎在问这个问题。@Jack感谢您提供解决方案的名称!我永远记不清具体问题的名称…非常酷的演示!让我很容易看到它的工作,现在我只是偷一点你的代码,并改变它一点,为我的工作。谢谢是的,我确实考虑过这一点,但现实的是,谁会等待所有的100个报价完成显示?(:谢谢你加入讨论!@theintellects:我在运行时考虑过这个问题,因为我的N1安卓手机的随机洗牌真的很糟糕。我认为这个算法是“作为下一个选择一首随机歌曲并播放”,而这,由于一个可怕的PRNG,真的很糟糕。
    var randomQuote = (function() {
      var quotes = ['quote 0','quote 1','quote 2'];
      var quoteCopy = [];
    
      return function () {
        if (!quoteCopy.length) {
          quoteCopy = quotes.slice();
        }
        return quoteCopy.splice(Math.random()*quoteCopy.length | 0, 1)[0];
      }
    }());