JS: How to choose random pairs of items from an array

Viewed 225

I have an array of PAIRS of 25 images (meaning a total of 50 images) each image path being in its own associative array.

const cardArray = [
    { name:'A', img:'images/A.jpg' },
    { name:'A', img:'images/A.jpg' },
    { name:'B', img:'images/B.jpg' },
    { name:'B', img:'images/B.jpg' },
    { name:'C', img:'images/C.jpg' },
    { name:'C', img:'images/C.jpg' },
    ...
    ... (bla bla bla, up to 25 times)
  ]

I know that if I have exactly 8 pairs then the function I can use is:

cardArray.sort(() => 0.5 - Math.random())

What I'd like to do is to randomly select 8 pairs of these images, then shuffle them like in a memory match game. How do I make it so that every time the user reloads the browser, different pairs of images from the array will load instead of the same 8 ones every time?

Thanks.

2 Answers

To select one card at random out of the card array it would just be:

const randomCard = Math.floor(Math.random() * cardArray.length);

The following will get you a random selection of 8 pairs of images from a total of 25 possible choices. The 16 images are then presented in a random order.

function shuffle(a,n){ // shuffle array a in place (Fisher-Yates)
 let m=a.length;
 n=n||m-1;
 for(let i=0,j;i<n;i++){
  j=Math.floor(Math.random()*(m-i)+i);
  if (j-i) [ a[i],a[j] ] = [ a[j],a[i] ]; // swap 2 array elements
 }
}
const a=[...new Array(25)].map((v,i)=>i);
shuffle(a,8);  // array of indices, like  [ 2, 13, 0, 7, 5, 24, 19, 8, ... ]
let sel=a.slice(0,8).map(k=>  // array of 8 image paths
 "images/"+String.fromCharCode(k+65)+".jpg");
sel=sel.concat(sel);          // double the array ...
shuffle(sel);                 // ... and shuffe it again

console.log(sel);
.as-console-wrapper {max-height: 100%  !important}

The approach is based on an array shuffle algorithm (Fisher-Yates) which I apply only for the first 8 elements. These elements are then extracted and presented as uppercase characters.

I took the liberty of rearranging your images object as an array of image names. The images are now picked twice (sel.concat(sel)) and shuffled again to present them in a random order.

Related