jQuery: Shuffle Plugin

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.

24 Comments

  1. Mike B. at

    Very nice script – thank you!

  2. Elle at

    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?

  3. caphun at

    @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.

  4. Pingback: Shuffling the DOM - James Padolsey

  5. Pingback: Implement Array Shuffling in MooTools

  6. Rustam Mester at

    Big thanks to author from russian freelancer !

  7. 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);
    });
    };

  8. caphun at

    @hector – makes sense to keep the bindings! I will add that into my code aswell. Thanks!

  9. Ellison at

    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.

  10. Thanks for the info. I appreciate it well.

  11. cordial at

    this is exactly what i needed!

    perfect, thanks!

  12. Deepak at

    really a good one… thanks for it.

  13. Alvein at

    Thanx. Powerfull script.. ;)

  14. 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’});

  15. 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);

  16. caphun at

    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. :)

  17. Blude at

    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.

  18. Blude at

    Nevermind. Just put my code wrapped inside (function($){

    })(jQuery); and now it’s working fine. Thanks!

  19. Pingback: Anonymous

  20. Maclean at

    Thanx, I was looking for this!

  21. michelle at

    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

  22. caphun at

    @michelle: best way to find out is test it. If you hit problems drop a test case here.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>