1

I have a problem where I can't get JS to print out 3 different values all the time, it sometimes pick dublicate values. Can anyone help?

var receivedArray = JSON.parse('<?php echo json_encode($unserialize);?>');
const random = receivedArray;
const correctAnswer = random[Math.floor(Math.random() * random.length)];
const guess1 = random[Math.floor(Math.random() * random.length)];
const guess2 = random[Math.floor(Math.random() * random.length)];


$(document).ready(function() {
  $("#test-div").append(
    "<div class=\"row\">\n" +
    "<div class=\"col-6\">\n" +
    "<img id=\"testImage\" src=\"\" alt='...' height=\"540px\"/>\n" +
    "</div>\n" +
    "<div class=\"col-6\">\n" +
    "<h4 class=\"Guess\" id=\"Guess\">ATMINI JŪRNIEKU MEZGLA NOSAUKUMU</h4>\n" +
    "<div id=\"shuffle\">" +
    "<div class=\"btn guesses\" >" + correctAnswer.nameLV + "</div><br>" +
    "<div class=\"btn guesses\" >" + guess1.nameLV + "</div><br>" +
    "<div class=\"btn guesses\" >" + guess2.nameLV + "</div>" +
    "</div>\n" +
    "</div>\n" +
    "</div>\n"

  );
  $("#testImage").attr("src", "../Images/uploads/" + correctAnswer.Image);
  console.log("BS")
});
Ivar
  • 6,138
  • 12
  • 49
  • 61
Renārs
  • 33
  • 5

4 Answers4

1

You should use splice() to remove items from the random array whenever an answer has been picked:

const correctAnswer = random.splice(Math.floor(Math.random() * random.length), 1);
const guess1 = random.splice(Math.floor(Math.random() * random.length), 1);
const guess2 = random.splice(Math.floor(Math.random() * random.length), 1);
1

Shuffle an array and then pick first three values

const [correctAnswer, guess1, guess2] = shuffle(random);

Take a shuffle function here or use lodash shuffle

function shuffle(array) {
  var currentIndex = array.length, temporaryValue, randomIndex;

  // While there remain elements to shuffle...
  while (0 !== currentIndex) {

    // Pick a remaining element...
    randomIndex = Math.floor(Math.random() * currentIndex);
    currentIndex -= 1;

    // And swap it with the current element.
    temporaryValue = array[currentIndex];
    array[currentIndex] = array[randomIndex];
    array[randomIndex] = temporaryValue;
  }

  return array;
}
0

Yes, it makes sense that if it just choosing a random item from a list, multiple times, that it would sometimes randomly choose the same item.

What you can instead do is remove the item once it has been randomly chosen. You can make a copy of the array first if you need to access the original later.

const random = [...receivedArray]; //copy
const correctAnswer= random.splice(Math.floor(Math.random() * random.length),1)[0];
const guess1 = random.splice(Math.floor(Math.random() * random.length),1)[0];
const guess2 = random.splice(Math.floor(Math.random() * random.length),1)[0];

Splice removes and returns a specified number of items. The 2nd argument you see there is the number to remove, which in your case is 1. Splice returns an array (even of one item), so then you have to add [0] to access the item itself.

Since the item will be removed, it can't be guessed again! Simple!

tmdesigned
  • 2,098
  • 2
  • 12
  • 20
0

randojs.com offers a simple and readable shuffle function specifically for this purpose. just shuffle with that randoSequence function and pop to get your values

var array = ["one", "two", "three"];
var shuffled = randoSequence(array);

console.log(shuffled.pop().value, shuffled.pop().value);
<script src="https://randojs.com/1.0.0.js"></script>
Aaron Plocharczyk
  • 2,776
  • 2
  • 7
  • 15