-3

I have 3 array variables with 10 element in each:

const groupA = ["Samuel", "Segun", "Daniel", "Toby", "John", "Malik", "Deji", "Wale", "Femi", "Jamal"];

const groupB = ["Niyola", "Diana", "Daniella", "Jane", "Cynthia", "Pamela", "Cassandra", "Feyi", "Esther", "Oyinda"];

const places = ["The Place", "Royale", "Eko hotel", "The Renaissance", "Arts Gallery", "Game center", "Sheraton", "Airport Hotel", "Harvey Garden", "Beverly Park"];

I used the random function to generate an element from each variables to match and print as:

Group A = Daniel and Group B = Cassandra will be going on a dinner date at Place = Airport Hotel.

How do I make the program not repeat groupA element until the array is exhausted?

Sunderam Dubey
  • 2,294
  • 9
  • 12
  • 22
  • 1
    I would create 3 new arrays (copies of the existing ones) and then randomly sort each of the copied arrays. Then, merely pick based on index - thus, the same 3 choices will not get picked unless we go and use the same index again. – jsN00b May 28 '22 at 12:40
  • 1
    Yes, to shuffle the arrays will be the key here. [Here is one way to do it](https://stackoverflow.com/a/67758525/2610061). – Carsten Massmann May 28 '22 at 13:03

1 Answers1

0

There are multiple possible approaches to the problem:

Shuffle and select

You could randomly shuffle the array using one of the described algorithms (Fisher–Yates shuffle, Durstenfeld shuffle) is this SO question and then simply loop over the shuffled arrays until one is exhausted.

const groupA = ["Samuel", "Segun", "Daniel", "Toby", "John", "Malik", "Deji", "Wale", "Femi", "Jamal"];
const groupB = ["Niyola", "Diana", "Daniella", "Jane", "Cynthia", "Pamela", "Cassandra", "Feyi", "Esther", "Oyinda"];
const places = ["The Place", "Royale", "Eko hotel", "The Renaissance", "Arts Gallery", "Game center", "Sheraton", "Airport Hotel", "Harvey Garden", "Beverly Park"];

/**
 * Generator function to return a tuple containing a random value from provided arrays until one of them is exhausted
 * @param {Array<Array<any>>} arrays
 */
function* selectRandomWithShuffle(...arrays) {
  arrays.forEach((array) => shuffleArray(array));
  // determine size of shortest array
  const min = Math.min(...arrays.map((array) => array.length));
  // get n-tuple (n == min) as long as there are n values available (i.e. until one of the array is exhausted)
  for (let i = 0; i < min; i++) {
    yield arrays.map((array) => array[i]);
  }
}

function shuffleArray(array) {
    for (var i = array.length - 1; i > 0; i--) {
        var j = Math.floor(Math.random() * (i + 1));
        var temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }
}

console.log([...selectRandomWithShuffle(groupA, groupB, places)]);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Credit: I re-used the shuffling algorithm provided by Laurens Holst in this SO post here.

Delete already selected items

Another possibility without shuffling would be to select one item of each array at random and delete that item from the array so that it cannot be used again.

const groupA = ["Samuel", "Segun", "Daniel", "Toby", "John", "Malik", "Deji", "Wale", "Femi", "Jamal"];
const groupB = ["Niyola", "Diana", "Daniella", "Jane", "Cynthia", "Pamela", "Cassandra", "Feyi", "Esther", "Oyinda"];
const places = ["The Place", "Royale", "Eko hotel", "The Renaissance", "Arts Gallery", "Game center", "Sheraton", "Airport Hotel", "Harvey Garden", "Beverly Park"];

/**
 * Generator function to return a tuple containing a random value from provided arrays until one of them is exhausted
 * @param {Array<Array<any>>} arrays
 */
function* selectRandomWithDelete(...arrays) {
  // create copy of arrays, to be able to delete items without affecting the original
  arrays = arrays.map(array => [...array]);
  // determine size of shortest array
  const min = Math.min(...arrays.map((array) => array.length));
  // get n-tuple (n == min) as long as there are n values available (i.e. until one of the array is exhausted)
  for (let i = 0; i < min; i++) {
    yield arrays.map((array) => selectRandElem(array));
  }
}

/**
   * Selects a random item from an array and removes that item from the array.
   * @param {Array<any>} array array to select an item from
   */
 function selectRandElem(array) {
    const idx = Math.floor(Math.random() * array.length);
    const selectedItem = array[idx];
    array.splice(idx, 1);
    return selectedItem;
  }

console.log([...selectRandomWithDelete(groupA, groupB, places)]);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Remarks

Disclaimer: I not affiliated, associated, authorized, endorsed by, or in any way officially connected with the "JavaScript for impatient programmers (ES2022 edition)" book by Dr. Axel Rauschmayer

Mushroomator
  • 3,491
  • 1
  • 5
  • 20