10

I am attempting to display a series of images in a random order. However, I do not want any single item to repeat until all items have been shown, so instead of selecting a random image from the array, I want to take the entire array, randomize it, and then select in sequence from the first to the last element. Here's my code:

HTML:

<div id="tout4"
<img src="images/gallery01.jpg" class="img_lg"/>
<img src="images/gallery02.jpg" class="img_lg"/>
<img src="images/gallery03.jpg" class="img_lg"/>
</div>

and the javascript, which currently selects and displays the items in order:

var galleryLength = $('#tout4 img.img_lg').length;
var currentGallery = 0;
setInterval(cycleGallery, 5000);


function cycleGallery(){

    $('#tout4 img.img_lg').eq(currentGallery).fadeOut(300);

    if (currentGallery < (galleryLength-1)){
        currentGallery++;
    } else {
        currentGallery = 0;
    }

    $('#tout4 img.img_lg').eq(currentGallery).fadeIn(300);
}

So how do I rearrange the actual order of the images, and not just the order in which they are selected?

mheavers
  • 29,530
  • 58
  • 194
  • 315

5 Answers5

17

After much exploration, I decided to take the fisher-yates algorithm and apply it with jquery without requiring cloning, etc.

$('#tout4 img.img_lg').shuffle();

/*
* Shuffle jQuery array of elements - see Fisher-Yates algorithm
*/
jQuery.fn.shuffle = function () {
    var j;
    for (var i = 0; i < this.length; i++) {
        j = Math.floor(Math.random() * this.length);
        $(this[i]).before($(this[j]));
    }
    return this;
};
Giacomo1968
  • 25,759
  • 11
  • 71
  • 103
chad steele
  • 828
  • 9
  • 13
  • thanks for this... so simple. the other answers are so complicated. – Tallboy Apr 20 '14 at 18:59
  • All of the "Math.random()-0.5" or "0.5-Math.random()" answers are provably incorrect. They do NOT produce a random result. (Why: sort() requires consistency in the comparison function and random() by definition is random rather than consistent.) The shuffle function does appear to be correct. – MrPete May 08 '17 at 16:14
  • This method is the best : easy, clean and functionnal, thanks – Nicolas Frbezar May 03 '18 at 13:01
  • Bricky, please consider deleting your comment. It's misleading. If you're convinced otherwise, please post a proof. – chad steele May 03 '19 at 19:26
  • @MrPete, can you elaborate on the consistency issue? Certainly for non-random sorting a consistent result is obviously necessary if a given pair of items is repeatedly compared; but when the desired output is a random order, it's not obvious to me that obtaining a random result from the comparison function will make the end result less random. – phils Jul 04 '19 at 03:18
8

You can also use the common JavaScript Array randomize sorter, also commented here and here:

$('<my selector>').sort( function(){ return ( Math.round( Math.random() ) - 0.5 ) } );
Community
  • 1
  • 1
fguillen
  • 36,125
  • 23
  • 149
  • 210
7

Ended up using this (thanks Blair!) -

/**
 * jQuery Shuffle (/web/20120307220753/http://mktgdept.com/jquery-shuffle)
 * A jQuery plugin for shuffling a set of elements
 *
 * v0.0.1 - 13 November 2009
 *
 * Copyright (c) 2009 Chad Smith (/web/20120307220753/http://twitter.com/chadsmith)
 * Dual licensed under the MIT and GPL licenses.
 * /web/20120307220753/http://www.opensource.org/licenses/mit-license.php
 * /web/20120307220753/http://www.opensource.org/licenses/gpl-license.php
 *
 * Shuffle elements using: $(selector).shuffle() or $.shuffle(selector)
 *
 **/
(function(d){d.fn.shuffle=function(c){c=[];return this.each(function(){c.push(d(this).clone(true))}).each(function(a,b){d(b).replaceWith(c[a=Math.floor(Math.random()*c.length)]);c.splice(a,1)})};d.shuffle=function(a){return d(a).shuffle()}})(jQuery);

So then the only additions that need to be made to the above code are to include the script, and call the shuffle function:

<script type="text/javascript" src="js/jquery-shuffle.js"></script>
$('#tout4 img.img_lg').shuffle();
Giacomo1968
  • 25,759
  • 11
  • 71
  • 103
mheavers
  • 29,530
  • 58
  • 194
  • 315
0
<!DOCTYPE html>
<html>
<body>

<p id="demo">Click the button to sort the array.</p>

<button onclick="myFunction()">Try it</button>

<script>
  function myFunction()
  {
    var points = [40,100,1,5,25,10];
    points.sort(function(a,b){return (Math.random()-0.5)});
    var x=document.getElementById("demo");
    x.innerHTML=points;
  }
</script>

</body>
</html>

Explanation: normally you have "return (a-b)" yielding a positive number for ascending sort order; or you have "return (b-a)" yielding a negative number for descending sort order.

Here we use Math.random()-0.5 which gives in half of the cases a positive number and in half of the cases a negative number. Thus sorting of pairs is either ascending or descending, yielding a random distribution of the array elements.

Giacomo1968
  • 25,759
  • 11
  • 71
  • 103
Stefan Gruenwald
  • 2,582
  • 24
  • 30
0

Short version for jQuery:

$('#tout4>').map(function(i,t) {
     var s=$(t).siblings();
     s.eq(Math.round(s.length*Math.random())).after(t)
})
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Dieter Bender
  • 37
  • 1
  • 2