1

I'm trying to make simple javascript quiz with like 10 questions, and show random 5 on each page load.

I have following code for questions:

var mojaPitanja = [
    {
        tekst: "What is the color of the sky?",
        odgovori: {
            a: 'Blue',
            b: 'Red',
            c: 'Green'
        },
        indeks_korektnog_odgovora: 'a'
    },
    {
        tekst: "In which country is located town Rome?",
        odgovori: {
            a: 'France',
            b: 'Austria',
            c: 'Italy'
        },
        indeks_korektnog_odgovora: 'c'
    },
    {
        tekst: "Who was Elvis Presley?",
        odgovori: {
            a: 'Singer',
            b: 'Writer',
            c: 'Dancer'
        },
        indeks_korektnog_odgovora: 'a'
    }
    ...................
];

Out of that list (with 10 questions) I want to get 5 random questions and show them on page.

This is the other part of the code I'm using to show the whole quiz on my page:

function generisiKviz(teksts, quizContainer, rezContainer, posaljiDugme){

    function prikazPitanja(teksts, quizContainer){
    // prostor za output i opcije odgovora
    var output = [];
    var odgovori;

    // za svako pitanje...
    for(var i=0; i<teksts.length; i++){
        
        // prvo resetujemo listu odgovora
        odgovori = [];

        // za svaku opciju odgovora na dato pitanje...
        for(letter in teksts[i].odgovori){

            // ...dodajemo radio button
            odgovori.push(
                '<label>'
                    + '<input type="radio" name="tekst'+i+'" value="'+letter+'">'
                    + letter + ': '
                    + teksts[i].odgovori[letter]
                + '</label>'
            );
        }

        // dodajemo specificno pitanje i odgovore za dato pitanje
        output.push(
            '<div class="pitanje"><div class="tekst">' + teksts[i].tekst + '</div>'
            + '<div class="odgovori">' + odgovori.join('') + '</div></div>'
        );
    }

    // finalni output koji se stavlja na stranicu
    quizContainer.innerHTML = output.join('');
}

    function showResults(teksts, quizContainer, rezContainer){
    
    // prikupljanje odgovora iz celog kviza
    var answerContainers = quizContainer.querySelectorAll('.odgovori');
    
    // sacuvati odgovore korisnika..
    var userAnswer = '';
    var numCorrect = 0;
    
    // za svako pitanje...
    for(var i=0; i<teksts.length; i++){

        // pronalazenje svakog odgovora
        userAnswer = (answerContainers[i].querySelector('input[name=tekst'+i+']:checked')||{}).value;
        
        // ako je odgovor tacan
        if(userAnswer===teksts[i].indeks_korektnog_odgovora){
            // dodati na sumarnu listu i sabrati koliko je tacnih...
            numCorrect++;
            
            // tacni odg zeleni
            answerContainers[i].style.color = 'green';
        }
        // ako je odgovor netacan ili prazan
        else{
            // boja je, logicno, crvena...
            answerContainers[i].style.color = 'red';
        }
    }

    // prikaz ukupnog broja tacnih odgovora od sumarnog broja pitanja
    rezContainer.innerHTML = numCorrect + ' pogođenih od ukupno ' + teksts.length;
}

    // prikaz odgovora
    prikazPitanja(teksts, quizContainer);

    // kad se klikne "posalji" dugme prikaz rezultata
    posaljiDugme.onclick = function(){
        showResults(teksts, quizContainer, rezContainer);
    }
}

var quizContainer = document.getElementById('quiz');
var rezContainer = document.getElementById('results');
var posaljiDugme = document.getElementById('submit');



And html:
<title>Page title</title>
<link rel="stylesheet" href="index.css">
<div id="quiz"></div>
<button id="submit">Pošalji odgovore</button> <button id="reloadfazon" onClick="window.location.reload()">Nova pitanja / reload</button>
<div id="results"></div>
<script src="script.js"></script> 


<script>
generisiKviz(mojaPitanja, quizContainer, rezContainer, posaljiDugme);
</script>

And html:

<title>Quiz project</title>
<link rel="stylesheet" href="index.css">
<div id="quiz"></div>
<button id="submit">Pošalji odgovore</button> <button id="reloadfazon" onClick="window.location.reload()">Nova pitanja / reload</button>
<div id="results"></div>
<script src="script.js"></script> 


<script>
generisiKviz(mojaPitanja, quizContainer, rezContainer, posaljiDugme);
</script>

I'm trying to use Math.floor(Math.random() but I'm lost. Any suggestions about the best approach here please? :)

Thanks!

Dzontra
  • 80
  • 2
  • 8
  • You can [shuffle](https://stackoverflow.com/a/2450976/5648954) your array and then grab the first 5 using [`.slice()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice) – Nick Parsons Jan 07 '23 at 23:26
  • so hard to search on google? https://bobbyhadz.com/blog/javascript-get-multiple-random-elements-from-array – Flash Thunder Jan 07 '23 at 23:40

2 Answers2

1

I guess shuffling is an option. But simple and logical would be to loop to 5 keeping randomizing an item which hasn't been chosen before.

questions = 10 // 1 based
pick = 5
chosen = [];
for (var i = 0; i < pick; i++) {
  do {
    r = Math.trunc(Math.random() * 10) + 1 // or other random function
  } while (chosen.indexOf(r) > -1)
  chosen.push(r)
}

console.log(chosen)
IT goldman
  • 14,885
  • 2
  • 14
  • 28
1

Math.random() gives you a number between 0 and 1, so if you want a number between 0 and 9 (for the index of the question list), you multiply this by 10 (to get a number between 0 and 10) and use Math.floor() to remove decimals and the possiblility of getting a ten. The code could look something like this:

your_questions_list = [...]
let chosen_questions = []
for (let i = 0; i < 5; i++) {
    let index = Math.floor(Math.random() * 10)
    while (chosen_questions.includes(index)){
        index = Math.floor(Math.random() * 10)
    }
    chosen_questions.push(i)
}
// and now to populate the list with actual questions

for (let i = 0; i < chosen_questions.length; i++) {
    chosen_questions[i] = your_questions_list[chosen_questions[i]];
}

console.log(chosen_questions);

This will give you a list (chosen_questions) of 5 random questions from the list of questions

Even better, to adapt to a varying question list size you could use the .length property of a list like this:

let index = Math.floor(Math.random() * your_questions_list.length))

Update:
Here's very short way of doing it (method is from comment above):

const shuffled = your_questions_list.sort(() => 0.5 - Math.random());
let selected = shuffled.slice(0, 5); // 5 is number of questions
Nasser Kessas
  • 359
  • 1
  • 13
  • Thanks! I'm just trying this but I'm a newbie in JS and still learning it. When I try to modify code that posted above it shows me empty list instead of 5 questions.. – Dzontra Jan 07 '23 at 23:40
  • Yes, I had a typo before, thanks for pointing that out. It should work now – Nasser Kessas Jan 07 '23 at 23:46
  • Thank you that was really helpful. However when I reload the page it is still showing the same 5 questions each time, and I wanted to show new random 5 (some of which can be repeated for sure, but this looks like it's always showing the same 5 questions), or I'm doing something wrong? – Dzontra Jan 07 '23 at 23:54
  • @Dzontra, I've added another very short way of doing it – Nasser Kessas Jan 07 '23 at 23:54
  • I'm pretty sure this isn't the algorithm's fault, when I re-run this on my computer I get different values each time. Maybe you got an old buggy version of my answer – Nasser Kessas Jan 07 '23 at 23:57