skip to Main Content

Currently, I am creating a random group generator. Right now, I have a for loop that creates a div and inserts it into a larger (parent?) div. In these smaller divs, I am using a random number to create a random index that is used to display random names.

Problem: However, I do not know how to make it so that after one index is chosen, it cannot be used again.

Question: How can I make a for loop that excludes a number after it is used once?

const inputArticle = document.querySelector('#input-article');
const inputForm = document.querySelector('#input-form');
const table = document.querySelector('#table');
const groupOptions = document.querySelector('select[ name="group-options" ]');
const createTeamsButton = document.querySelector('#create-teams-button');
const outputArticle = document.querySelector('#output-article');
const outputMainDiv = document.querySelector('#output-main-div');

let peopleArray = [];
let numberPeople = 0;
let rowNumber = 0;
let groupNumber = 1;
let maxPeopleInGroup = 0;
let maxNumberGroups = 0;

function addRow(person) {
    let row = table.tBodies[0].insertRow(-1);
    let cell1 = row.insertCell(0);
    let cell2 = row.insertCell(1);
    let cell3 = row.insertCell(2);
    let removeButton = document.createElement("button");

    cell1.style.width = "5vmin";
    cell1.style.height = "5vmin";
    cell1.style.fontSize = "18pt";
    cell1.style.fontWeight = "300";

    cell2.style.width = "5vmin";
    cell2.style.height = "5vmin";
    cell2.style.fontSize = "18pt";
    cell2.style.fontWeight = "300";

    cell3.style.width = "5vmin";
    cell3.style.height = "5vmin";
    cell3.style.fontSize = "18pt";
    cell3.style.fontWeight = "300";
    
    removeButton.dataset = person;
    removeButton.innerText = `Remove ${person.firstName} ${person.lastName}`;
    removeButton.setAttribute("type", "button");

    removeButton.addEventListener('click', (event) => {
        peopleArray = peopleArray.filter(p => p != person);
        row.remove();
    })

    cell1.innerText = person.firstName;
    cell2.innerText = person.lastName;
    cell3.appendChild(removeButton);
}

function createNames(event) {
    let person = {
        firstName:  document.getElementById(`firstName`).value,
        lastName: document.getElementById(`lastName`).value
    }

    event.target.reset();
    addRow(person);
    peopleArray.push(person);
    numberPeople++;
    //alert(JSON.stringify(peopleArray));
}

function submit() {
    if (groupOptions.value != "") {
        inputArticle.classList.add("hidden");
        outputArticle.classList.remove("hidden");
        createGroups();
    }
}

function createGroups() {
    maxPeopleInGroup = groupOptions.value;
    maxNumberGroups = Math.floor(maxPeopleInGroup / peopleArray.length);
    let divWidth = 5 * maxPeopleInGroup;
    let divHeight = 7.5 * maxPeopleInGroup;

    while (numberPeople / maxPeopleInGroup > maxNumberGroups) {
        maxNumberGroups++;
    }

    for (let i = 0; i < maxNumberGroups; i++) {
        let div = document.createElement("div");
        div.setAttribute("id", `group${groupNumber}`);
        div.style.width = `${divWidth}vw`;
        div.style.height = `${divHeight}vh`;
        div.style.textAlign = "center";
        div.style.alignItems = "center";
        div.style.fontFamily = "Georgia, 'Times New Roman', Times, serif";
        div.style.fontSize = "18pt";
        div.style.fontWeight = "400";
        div.style.border = "1px solid black";
        outputMainDiv.appendChild(div);
        div.innerHTML = `Group ${groupNumber}:</br>`;

        for (let k = 0; k < maxPeopleInGroup; k++) {
            let index = Math.round(Math.random() * peopleArray.length);
            div.innerHTML += `${peopleArray[index].firstName} ${peopleArray[index].lastName} </br>`;
        }

        groupNumber++;
    }
}     

inputArticle.classList.remove("hidden");
outputArticle.classList.add("hidden");

window.addEventListener('keydown', (event) => {
    if (event.key == 'Enter') {
        if (firstName.value && lastName.value) {
            createNames(event);
        }    
    }
}, false)

inputForm.addEventListener("submit", (event) => {
   createNames(event);
   event.target.reset();
})

createTeamsButton.addEventListener('click', submit);
#input-article.hidden {
    display: none;
}

table {
    text-align: center;
    align-items: center;
    border: 1px solid black;
    border-collapse: collapse;
}

th {
    width: 50vmin;
    height: 10vmin;
    font-size: 20pt;
    font-weight: 800;
}

input {
    width: 50vmin;
    height: 5vmin;
    text-align: center;
    align-items: center;
    font-size: 18pt;
    font-weight: 500;
    font-family: Georgia, 'Times New Roman', Times, serif;
    border: 0;
    padding: 0;
}

#group {
    display: flex;
    flex-wrap: wrap;
}

#output-article.hidden {
    display: none;
}

#output-main-div {
    width: 95vw; /*Percentage width of browser*/ 
    height: 95vh; /*Percentage height of browser*/
    border: 1px solid black;
}

#input-article p, #input-article option {
    font-size: 18pt;
}
<!DOCTYPE html>
<html lang="en">

<html>
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE-edge">
        <meta name="viewport", content="width=device-width, initial-scale=1.0">
    </head>

    <body>
        <article id="input-article">
            <form method="dialog" id="input-form">
                <table id="table" border="1">
                    <thead>
                        <tr>
                            <th>First Name:</th>
                            <th>Last Name:</th>
                            <th>Actions</th>
                        </tr>
                    </thead>
                    
                    <tbody></tbody>

                    <tfoot>
                        <tr>
                            <td><input name="first-name" type="text" required placeholder="First Name" id="firstName"></td>
                            <td><input name="last-name" type="text" required placeholder="Last Name" id="lastName"></td>
                            <td>
                                <button type="submit">Add Person</button>
                                <button type="reset">Clear Names</button>
                            </td>
                        </tr>
                    </tfoot>
                </table> 
            </form><br>

            <div id="group">
                <p>Number of people per group:&nbsp;</p>
                <select name = "group-options" required>
                    <option value="">--Select Answer--</option>
                    <option value="2">2</option>
                    <option value="3">3</option>
                    <option value="4">4</option>
                    <option value="5">5</option>
                    <option value="6">6</option>
                    <option value="7">7</option>
                    <option value="8">8</option>
                    <option value="9">9</option>
                    <option value="10">10</option>
                    <option value="11">11</option>
                    <option value="12">12</option>
                </select>
            </div>    

            <div id="buttons">
                <button id="create-teams-button">Randomize Teams</button>
            </div>
        </article>

        <article id="output-article">
            <div id="output-main-div"></div>
        </article>
    </body>
</html>

2

Answers


  1. Keep moving your already chosen elements to the start of the list, and then pick from the remaining elements in the array.

        for (let k = 0; k < maxPeopleInGroup; k++) {
            // subtract k from the random possibilities and then add after to ignore previously 
            let index = Math.round(Math.random() * (peopleArray.length - k)) + k; chosen elements)
            div.innerHTML += `${peopleArray[index].firstName} ${peopleArray[index].lastName} </br>`;
            //swap array elements
            let temp = peopleArray[k];
            peopleArray[k] = peopleArray[index];
            peopleArray[index] = temp;
        }
    
    Login or Signup to reply.
  2. You can just change the order of the people array and then use it to loop over each item in sequential order.

    The following function takes an array as input and returns it with the items in random order:

    function shuffle(array) {
      for (let i = array.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        [array[i], array[j]] = [array[j], array[i]];
      }
      return array;
    }
    

    On each iteration, j is always assigned to a number within the range determined by the current value of i. Finally, array[i] is being swapped with array[j] using destructuring assignment syntax.

    You can use it as follows:

    const people = [
      {first: "john", last: "doe"},
      {first: "jane", last: "doe"},
      {first: "jack", last: "doe"},
    ];
    
    shuffle(people).forEach(person => {
      console.log(person.first, person.last);
    });
    
    // Example output: jane doe, jack doe, john doe
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search