Shuffle multiple arrays in the same way but with Lodash

I’ve got two arrays

const mp3 = ['sing.mp3','song.mp3','tune.mp3','jam.mp3',etc];
const 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:

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

There’s a few posts on stackoverflow that shuffle arrays in the way I described —this one is pretty great— but none of them demonstrate how to shuffle two arrays using Lodash.

The JavaScript methods library is known as weak, it has the sort() method but it doesn’t have the shuffle() method, thus, all the answers are mixing the logic of shuffling an array & And & keeping the shuffle identical among multiple arrays. Therefore I thought that creating a separate question here would be a great idea.

and for the shuffeling part of the algorithm, I chose Lodash, since I’m using it, and it’s the most popular JavaScript utilities library out there.

thnx!

>Solution :

One simple approach is to just shuffle the array of indices and then use that to get both your arrays in the corresponding order:

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

const indices = _.shuffle([0, 1, 2, 3]);

const shuffledMp3 = indices.map(idx => mp3[idx]);
const shuffledOgg = indices.map(idx => ogg[idx]);

console.log(shuffledMp3, shuffledOgg);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>

However, you shouldn’t need to do this. Your question only arises because you’re storing the data in an unhelpful way. Since the elements of the two arrays are clearly linked to each other, you shouldn’t store them as 2 arrays, but as a single array whose elements are objects holding both filenames as properties. This enables you to get what you want with a single shuffle:

const files = [{mp3: 'sing.mp3', ogg: 'sing.ogg'}, {mp3: 'song.mp3', ogg: 'song.ogg'}, {mp3: 'tune.mp3', ogg: 'tune.ogg'}, {mp3: 'jam.mp3', ogg: 'jam.ogg'}];

const shuffled = _.shuffle(files);

console.log(shuffled.map(file => file.mp3));
console.log(shuffled.map(file => file.ogg));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>

(It’s also worth noting that if all your file names are as predictably formed as in your example, even this is unnecessary – you can just store the "raw" filenames: ['sing', 'song', 'tune', 'jam'] and add whatever file extension you need at the point of needing it. But perhaps your real data is not so consistent.)

Leave a Reply