Reputation: 1370
I have a small snippet of Javascript where I rotate through a list of quotes in order from beginning to end.
However, I want to randomly go through the list (instead of in order), without repeating until all of the quotes are iterated through, and then start around with a random quote again. How would I go about doing this?
$(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);
});
Upvotes: 1
Views: 203
Reputation: 94101
Here's a possible solution with demo:
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();
Demo: http://jsbin.com/agihix/1/edit
Edit: I turned this into a little plugin, grab it here https://gist.github.com/elclanrs/5610886
Upvotes: 2
Reputation: 114491
I don't think your algorithm as stated is good. Suppose you have 100 quotes and then you make a first random presentation of the full set.
At the end, as stated in your description, will start again from scratch and so it's possible that quote 101 will be the same quote as 100.
I think that something better (more uniform) would be
n
quotes. This is done only once at the beginning.n-w
and n
where w
is a parameter (e.g. n/2
).The number w
will modulate how much random you want the sequence to be... the smaller and the more uniform the delay will be after a quote is presented.
With this approach there will be no "distribution glitch" and the average delay after which a quote is presented next time will not depend on the current position.
Upvotes: 0
Reputation: 147413
The following copies the quote array, then randomly slices one from it each time. wWen there are no entries left, it starts again.
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];
}
}());
Upvotes: 0
Reputation: 64657
Just to show the Fisher Yates (not my code):
function fisherYates ( myArray ) {
var i = myArray.length, j, temp;
if ( i === 0 ) return false;
while ( --i ) {
j = Math.floor( Math.random() * ( i + 1 ) );
temp = myArray[i];
myArray[i] = myArray[j];
myArray[j] = temp;
}
return myArray;
}
So get your quotes into an array, run it through that function, then do loop through the array, when you get to the end, run it through that function again, etc.
Upvotes: 0