Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shuffle multiple javascript arrays in the same way

I've got two arrays

var mp3 = ['sing.mp3','song.mp3','tune.mp3','jam.mp3',etc];
var ogg = ['sing.ogg','song.ogg','tune.ogg','jam.ogg',etc];

i need to shuffle both arrays so that they come out the same way, ex:

var mp3 = ['tune.mp3','song.mp3','jam.mp3','sing.mp3',etc];
var ogg = ['tune.ogg','song.ogg','jam.ogg','sing.ogg',etc];

there's a few posts on stackoverflow that shuffle arrays in different ways--this one is pretty great--but none of them demonstrate how to shuffle two arrays in the same exact way.

thnx!

like image 781
Nick Briz Avatar asked Nov 06 '25 05:11

Nick Briz


2 Answers

Add an extra argument to the Fisher-Yates shuffle. (assumes that your arrays are equal length)

var mp3 = ["sing.mp3", "song.mp3"];
var ogg = ["sing.ogg", "song.ogg"];

function shuffle(obj1, obj2) {
  var index = obj1.length;
  var rnd, tmp1, tmp2;

  while (index) {
    rnd = Math.floor(Math.random() * index);
    index -= 1;
    tmp1 = obj1[index];
    tmp2 = obj2[index];
    obj1[index] = obj1[rnd];
    obj2[index] = obj2[rnd];
    obj1[rnd] = tmp1;
    obj2[rnd] = tmp2;
  }
}

shuffle(mp3, ogg);

console.log(mp3, ogg);

UPDATE:

If you are going to support more arrays (as suggested in the comments), then you could modify the Fisher-Yates as follows (aswell as perform some checks to make sure that the arguments are of Array and that their lengths match).

var isArray = Array.isArray || function(value) {
  return {}.toString.call(value) !== "[object Array]"
};

var mp3 = ["sing.mp3", "song.mp3", "tune.mp3", "jam.mp3"];
var ogg = ["sing.ogg", "song.ogg", "tune.ogg", "jam.ogg"];
var acc = ["sing.acc", "song.acc", "tune.acc", "jam.acc"];
var flc = ["sing.flc", "song.flc", "tune.flc", "jam.flc"];

function shuffle() {
  var arrLength = 0;
  var argsLength = arguments.length;
  var rnd, tmp;

  for (var index = 0; index < argsLength; index += 1) {
    if (!isArray(arguments[index])) {
      throw new TypeError("Argument is not an array.");
    }

    if (index === 0) {
      arrLength = arguments[0].length;
    }

    if (arrLength !== arguments[index].length) {
      throw new RangeError("Array lengths do not match.");
    }
  }

  while (arrLength) {
    rnd = Math.floor(Math.random() * arrLength);
    arrLength -= 1;
    for (argsIndex = 0; argsIndex < argsLength; argsIndex += 1) {
      tmp = arguments[argsIndex][arrLength];
      arguments[argsIndex][arrLength] = arguments[argsIndex][rnd];
      arguments[argsIndex][rnd] = tmp;
    }
  }
}

shuffle(mp3, ogg, acc, flc);

console.log(mp3, ogg, acc, flc);
like image 58
Xotic750 Avatar answered Nov 08 '25 00:11

Xotic750


From that example, simply add a second parameter (your second array) and perform the operation on both arrays. You will just need to add and use a second temp, so you aren't overwriting your temps.

This should do the trick ASSUMING THE ARRAYS ARE THE SAME LENGTH:

function shuffle(array, array2) {
    var counter = array.length, temp, temp2, index;

    // While there are elements in the array
    while (counter > 0) {
        // Pick a random index
        index = Math.floor(Math.random() * counter);

        // Decrease counter by 1
        counter--;

        // And swap the last element with it
        temp = array[counter];
        temp2 = array2[counter];

        array[counter] = array[index];
        array2[counter] = array2[index];

        array[index] = temp;
        array2[index] = temp2;
    }
}
like image 39
Tricky12 Avatar answered Nov 08 '25 00:11

Tricky12