I recently came across a really compact array shuffling function on JSFromHell.com, which I thought would make a nifty jQuery plugin.
This jQuery shuffle plugin could be applied to any HTML element or Array object.
(function($){
$.fn.shuffle = function() {
return this.each(function(){
var items = $(this).children();
return (items.length)
? $(this).html($.shuffle(items))
: this;
});
}
$.shuffle = function(arr) {
for(
var j, x, i = arr.length; i;
j = parseInt(Math.random() * i),
x = arr[--i], arr[i] = arr[j], arr[j] = x
);
return arr;
}
})(jQuery);
Due to line wrapping issues in this post I inserted a few hard carriage returns in the above snippet (sorry).
Example 1: shuffle an unordered list
$('ul').shuffle();
Example 2: shuffle an array
var arr = [1,2,3,4,5,6]; arr = $.shuffle(arr);
There is a demo here. And for those interested I encourage you to download the plugin for closer inspection.

Nice work! =)
Very nice script – thank you!
Nice script. Could I ask for your help on how to alter the script so it shuffles through an array but only shows just one array item — which would change on page reload?
@Elle: Thanks. Yes that’s certainly possible. Try this:
jQuery(function($){
var randomItem = $.shuffle([1,2,3,4,5,6])[0];
alert(randomItem);
});
The above will return a random number between 1 and 6.
Pingback: Shuffling the DOM - James Padolsey
Pingback: Implement Array Shuffling in MooTools
Big thanks to author from russian freelancer !
Thanks mate!
Very nice! Just what I was looking for and it seems quick.
But I ran into a small problem — all event bindings will be lost after shuffling. I made a small modification that allows you to keep your bindings by using clone(true):
$.fn.shuffle = function()
{
return this.each(function()
{
var items = $(this).children().clone(true);
return (items.length)
? $(this).html($.shuffle(items))
: this);
});
};
@hector – makes sense to keep the bindings! I will add that into my code aswell. Thanks!
Hello. I’ve made an attempt at extending this plugin a little to be able to seed a random number generator so that you can repeat sequences given the right seed. I’m very new at jQuery, so if I didn’t do something quite right (style-wise or other), please tell me
(function($){
var getNextRandom = Math.random;
$.fn.shuffle = function() {
return this.each(function(){
var items = $(this).children().clone(true);
return (items.length) ? $(this).html($.shuffle(items)) : this;
});
}
$.shuffleInit = function(options) {
if(!options || !Random) return;
if(typeof options.seed == “number”) {
var r = new Random(options.seed);
getNextRandom = function() { return r.next(); };
}
}
$.shuffle = function(arr) {
for(var j, x, i = arr.length; i; j = parseInt(getNextRandom() * i), x = arr[--i], arr[i] = arr[j], arr[j] = x);
return arr;
}
})(jQuery);
It seems to work fine, assuming that you’ve loaded a class called Random that works appropriately (i.e. a 1-arg constructor to initialize the seed and a next() method to get the next pseudo-random number).
Again, I’d much appreciate tips on how I can improve what I was trying to do.
Thanks for the info. I appreciate it well.
this is exactly what i needed!
perfect, thanks!
really a good one… thanks for it.
Thanx. Powerfull script..
I think that I found an amelioration for the plugin shuffle
I did (function($){ $.fn.shuffle = function(options) { defaults = { children: '', after:'', inside:'' } if(options) params = $.extend(defaults,options); return this.each(function(){ var items = $(this).find(params.children).clone(true); if(items.length){ $(this).children(params.children).remove(); if(params.after) return $.shuffle(items).insertAfter($(this).find(params.after)); if(params.inside) return $(this).find(params.inside).html($.shuffle(items)); else return $(this).html($.shuffle(items)); } else return this; }); } $.shuffle = function(arr) { for(var j, x, i = arr.length; i; j = parseInt(Math.random() * i), x = arr[--i], arr[i] = arr[j], arr[j] = x); return arr; } })(jQuery);example 1
$(‘div’).shuffle({‘children’:’.shuffle’,'after’:’.field’});
Example 2
$(‘.random’).shuffle({‘children’:'select > option:gt(0)’,'after’:'select > option:lt(1)’});
Example 3
$(‘.random’).shuffle({‘children’:'select > option:gt(0)’,'inside’:'select’});
I made some code changes :
(function($){
$.fn.shuffle = function(options) {
defaults = {
children: ”,
after:”,
inside:”
}
params = $.extend(defaults,options);
return this.each(function(){
if(params.children) var element = $(this).find(params.children);
else var element = $(this).children();
var items = element.clone(true);
if(items.length){
element.remove();
if(params.after)
return $.shuffle(items).insertAfter($(this).find(params.after));
if(params.inside)
return $(this).find(params.inside).html($.shuffle(items));
else return $(this).html($.shuffle(items));
}
else return this;
});
}
$.shuffle = function(arr) {
for(var j, x, i = arr.length; i; j = parseInt(Math.random() * i), x = arr[--i], arr[i] = arr[j], arr[j] = x);
return arr;
}
})(jQuery);
I put .shuffle() up on github here:
http://github.com/caphun/jquery.shuffle
Feel free to fork it, modify and extend. Let me know if you do as I’m very much interested in how others will use this.
I’m not an expert on JavaScript but this seemed to works fine when I was testing local but when I uploaded to my blog it stopped working. It actually says that $.shuffle is not a function. Thanks for any suggestion on what might be causing this.
Nevermind. Just put my code wrapped inside (function($){
…
})(jQuery); and now it’s working fine. Thanks!
Pingback: Anonymous
Thanx, I was looking for this!
what if its a multi dimensional array, will it shuffle just the rows or the whole array? sounds like a silly qu but quite imp. thanks
@michelle: best way to find out is test it. If you hit problems drop a test case here.