0

I have this function that shows two random images picked from a folder. Is there any chance I can modify the code so that I won't have the same image twice as result?

Thanks in advance.

var theImages = new Array()

theImages[0] = 'img/dyptichs/f-1.jpg'
theImages[1] = 'img/dyptichs/f-2.jpg'
theImages[2] = 'img/dyptichs/f-3.jpg'
theImages[3] = 'img/dyptichs/f-4.jpg'
theImages[4] = 'img/dyptichs/f-5.jpg'

var j = 0
var p = theImages.length;
var preBuffer = new Array()
for (i = 0; i < p; i++){
   preBuffer[i] = new Image()
   preBuffer[i].src = theImages[i]
}
var WI1 = Math.round(Math.random()*(p-1));
var WI2 = Math.round(Math.random()*(p-2));

function showImage1(){
document.write('<img src="'+theImages[WI1]+'">');
}
function showImage2(){
document.write('<img src="'+theImages[WI2]+'">');
}
Federico
  • 1,392
  • 1
  • 17
  • 40

3 Answers3

3

You can do something like this:

var WI1 = Math.round(Math.random()*(p-1));
var WI2 = Math.round(Math.random()*(p-1));
while (WI2 === WI1) {
    WI2 = Math.round(Math.random()*(p-1));
}

We keep generating a new number until it's different from WI1, ensuring it is unique.

Terry Lennox
  • 29,471
  • 5
  • 28
  • 40
2

The way I'd personally handle that is to randomise the array and then just grab the first 2 entries. That way you still pick 2 at random, but you guarantee not to get the same 2.

var theImages = new Array()

theImages[0] = 'img/dyptichs/f-1.jpg'
theImages[1] = 'img/dyptichs/f-2.jpg'
theImages[2] = 'img/dyptichs/f-3.jpg'
theImages[3] = 'img/dyptichs/f-4.jpg'
theImages[4] = 'img/dyptichs/f-5.jpg'

var randomImages = theImages
    .concat()
    .sort(function () {

        return Math.random() > 0.5
            ? 1
            : -1;

    })
    .slice(0, 2);

function showImage1() {
    document.write('<img src="' + randomImages[0] + '">');
}

function showImage2() {
    document.write('<img src="' + randomImages[1] + '">');
}

Edit: including the original array for a complete solution

James Long
  • 4,629
  • 1
  • 20
  • 30
  • Where would you put the array though? – Federico Jul 02 '18 at 13:52
  • @Federico sorry, I don't understand the question. `randomImages` is the array, it's in the current scope (which looks like the global scope to me). Does that answer your question? – James Long Jul 02 '18 at 13:54
  • Yeah but the images are inside a folder and here it's not specified? – Federico Jul 02 '18 at 13:55
  • They're already specified in `theImages`. All I'm doing is creating a version of the `theImages` array with a random order and calling it `randomImages` – James Long Jul 02 '18 at 13:56
  • 1
    Sort with random comparator is not the correct way to shuffle a sequence, as it will not give uniformly random results. – riv Jul 02 '18 at 13:56
  • 1
    @riv you're absolutely right. I wanted a simple solution to explain quickly, but there are much better shuffling solutions around. For example in this answer https://stackoverflow.com/a/2450976/557019 – James Long Jul 02 '18 at 13:58
1
var WI1 = Math.floor(Math.random()*p);
var WI2 = Math.floor(Math.random()*(p-1));
if (WI2 >= WI1) {
  WI2 += 1;
}

Use floor instead of round and subtract 1, because with round you get twice less chance to get first or last element.

The if trick is slightly better than a loop in this case, though the loop is easier to apply to a more complex case.

riv
  • 6,846
  • 2
  • 34
  • 63