0

I have an array and the idea behind is to take these value from said array and add them to HTML buttons which would serve as questions for a quiz. I got the code to take the values from the array randomly, but the issue I have is that I sometimes get two buttons with the same value added, instead of each button being a unique entry from the array. The array itself doesn't contain duplicates.

const genres = ["Crime", "Action", "Drama", "Thriller", "Horror", "Comedy", "History", "Romance", "Adventure", "Epic", "Sci-Fi"];

let answers = document.querySelectorAll('.answer');
[].forEach.call(answers, function(answers) {
  randGenres = Math.floor(Math.random() * genres.length);
  answers.innerHTML = genres[randGenres];
});
<div class="container">

  <h5 class="modal-title">Modal title</h5>
  <div class="question">

  </div>
  <button class="answer">Some Answer</button>
  <button class="answer">Some Answer</button>
  <button class="answer">Some Answer</button>
  <button class="answer">Some Answer</button>
</div>
mplungjan
  • 169,008
  • 28
  • 173
  • 236
Nick94
  • 3
  • 3
  • you could [shuffle](https://stackoverflow.com/questions/2450954/how-to-randomize-shuffle-a-javascript-array) your array first and then sequentially go through your array to take elements (which would be in random order) – Nick Parsons Sep 06 '21 at 12:53
  • PS: `[].forEach.call(answers, function(answers) {` can be written more readble as `answers.forEach(answer => { answer.innerHTML .... })` – mplungjan Sep 06 '21 at 13:18

2 Answers2

0

Shuffle the array before assigning

const fy = (a,b,c,d) => { // https://stackoverflow.com/a/25984542/295783
 c=a.length;while(c)b=Math.random()*(--c+1)|0,d=a[c],a[c]=a[b],a[b]=d
}
const genres = ["Crime", "Action", "Drama", "Thriller", "Horror", "Comedy", "History", "Romance", "Adventure", "Epic", "Sci-Fi"];

let answers = document.querySelectorAll('.answer');
const rand = genres.slice(0); // we can save a few statements here if you do not mind modifying the original array
fy(rand)
answers.forEach(answer => answer.textContent = rand.pop())
<div class="container">

  <h5 class="modal-title">Modal title</h5>
  <div class="question">

  </div>
  <button class="answer">Some Answer</button>
  <button class="answer">Some Answer</button>
  <button class="answer">Some Answer</button>
  <button class="answer">Some Answer</button>
</div>
mplungjan
  • 169,008
  • 28
  • 173
  • 236
0

This is because the randomization logic you used will always consider all the genres even if it was already rendered before.

The solution to this is to "remove" already-selected items from the array before you randomize again on the next iteration.

Here's the updated code:

let genres = ["Crime", "Action", "Drama", "Thriller", "Horror", "Comedy", "History", "Romance", "Adventure", "Epic", "Sci-Fi"];

let answers = document.querySelectorAll('.answer');
[].forEach.call(answers, function(answers) {
    randGenres = Math.floor(Math.random() * genres.length);
    answers.innerHTML = genres[randGenres];

    // let's remove the selected item from
    genres.splice(randGenres, 1);
});