skip to Main Content

I have the code for a MCQ app that uses HTML, CSS, and JS. The code asks all the questions that are in the array object (which in this case is 8). However, I want the app to select only five random questions from the list of questions.

const quizData = [
    {
        question: "What is the most used programming language in 2019?",
        a: "Java",
        b: "C",
        c: "Python",
        d: "JavaScript",
        correct: "d",
    },
    {
        question: "Who is the President of US?",
        a: "Florin Pop",
        b: "Donald Trump",
        c: "Ivan Saldano",
        d: "Mihai Andrei",
        correct: "b",
    },
    {
        question: "What does HTML stand for?",
        a: "Hypertext Markup Language",
        b: "Cascading Style Sheet",
        c: "Jason Object Notation",
        d: "Helicopters Terminals Motorboats Lamborginis",
        correct: "a",
    },
    {
        question: "What year was JavaScript launched?",
        a: "1996",
        b: "1995",
        c: "1994",
        d: "none of the above",
        correct: "b",
    },
    {
        question: "Which is the largest animal in the world?",
        a: "Shark",
        b: "Blue Whale",
        c: "Elephant",
        d: "Giraffe",
        correct: "b",
    },
    {
        question: "Which is the smallest country in the world?",
        a: "Vatican City",
        b: "Bhutan",
        c: "Nepal",
        d: "Sri Lanka",
        correct: "a",
    },
    {
        question: "Which is the largest desert in the world?",
        a: "Kalahari",
        b: "Gobi",
        c: "Sahara",
        d: "Antarctica",
        correct: "d",
    },
    {
        question: "Which is the smallest continent in the world?",
        a: "Asia",
        b: "Australia",
        c: "Arctic",
        d: "Africa",
        correct: "b",
    },
];

const quiz = document.getElementById("quiz");
const answerEls = document.querySelectorAll(".answer");
const questionEl = document.getElementById("question");
const a_text = document.getElementById("a_text");
const b_text = document.getElementById("b_text");
const c_text = document.getElementById("c_text");
const d_text = document.getElementById("d_text");
const submitBtn = document.getElementById("submit");

let currentQuiz = 0;
let score = 0;

loadQuiz();

function loadQuiz() {
    deselectAnswers();

    const currentQuizData = quizData[currentQuiz];

    questionEl.innerText = currentQuizData.question;
    a_text.innerText = currentQuizData.a;
    b_text.innerText = currentQuizData.b;
    c_text.innerText = currentQuizData.c;
    d_text.innerText = currentQuizData.d;
}

function getSelected() {
    let answer = undefined;

    answerEls.forEach((answerEl) => {
        if (answerEl.checked) {
            answer = answerEl.id;
        }
    });

    return answer;
}

function deselectAnswers() {
    answerEls.forEach((answerEl) => {
        answerEl.checked = false;
    });
}

submitBtn.addEventListener("click", () => {
    // check to see the answer
    const answer = getSelected();

    if (answer) {
        if (answer === quizData[currentQuiz].correct) {
            score++;
        }

        currentQuiz++;
        if (currentQuiz < quizData.length) {
            loadQuiz();
        } else {
            quiz.innerHTML = `
                <h2>You answered correctly at ${score}/${quizData.length} questions.</h2>

                <button onclick="location.reload()">Reload</button>
            `;
        }
    }
});

I know that I can use the random function like this within some kind of loop:

Math.floor(Math.random() * quizData.length);

But I am not sure how to use this within the code.
The project is here: codepen

3

Answers


  1. Rename quizData to quizSource and create a new array quizData – then your existing code will work as-is (using quizData).

    Copy questions from quizSource -> quizData at the start of the quiz.

    As a first step, simply loop until you have enough questions:

    let quizSource = ["Q1", "Q2", "Q3", "Q4", "Q5", "Q6", "Q7", "Q8" ]; // simplified for demo
    let quizData = [];
    
    for (let i=0;i<5;++i)
      quizData.push(quizSource[i]);
     
    console.log(quizData);

    Next step it to determine random questions, but works essentially the same way, copy questions to quizData from quizSource.

    Using your Math.floor(Math.random() * quizSource.length) to determine a random index, you can then use .includes to determine if it’s already included

    if (quizData.includes(idx))
      // already have this idx
    

    which can be implemented in a while loop to keep getting indexes until you hit one that you haven’t previous used.

    NB: the for limit must be less than or equal to the source.length otherwise you get an infinite loop. Always add limit checks (not included here for clarity)

    var quizSource = [
        {Name:"Q1"}, {Name:"Q2"}, {Name:"Q3"}, {Name:"Q4"}, {Name:"Q5"}, {Name:"Q6"}, {Name:"Q7"}, {Name:"Q8"} 
    ]; // simplified for demo
    let quizData = [];
    
    function newQuizData() {
      quizData = [];
      for (let i=0;i<5;++i)
      {
        let idx = Math.floor(Math.random() * quizSource.length);
        while (quizData.includes(idx))
          idx = Math.floor(Math.random() * quizSource.length);
    
        quizData.push(quizSource[idx]);
      }
    }
     
    newQuizData();
    console.log(quizData);
    
    newQuizData();
    console.log(quizData);
    view browser console for results

    Then call newQuziData() at the start of your quiz

    Login or Signup to reply.
  2. I update the loadQuiz function

    function loadQuiz() {
        deselectAnswers();
        selectedElements.length = 0;
        const selectedElements = [];
        const numElementsToSelect = 5;
        while (selectedElements.length < numElementsToSelect) {
            const randomIndex = Math.floor(Math.random() * quizData.length);
            const randomElement = quizData[randomIndex];
        
            if (!selectedElements.includes(randomElement)) {
                selectedElements.push(randomElement);
            }
        }
    
        if (currentQuiz < numElementsToSelect) {
            const currentQuizData = selectedElements[currentQuiz];
    
            questionEl.innerText = currentQuizData.question;
            a_text.innerText = currentQuizData.a;
            b_text.innerText = currentQuizData.b;
            c_text.innerText = currentQuizData.c;
            d_text.innerText = currentQuizData.d;
        }
    }
    

    and in submitBtn EventListener update if condition:

    // numElementsToSelect instead of quizData.length
      if (currentQuiz < numElementsToSelect) {
                loadQuiz();
          }
    
    Login or Signup to reply.
  3. You can shallow copy the array and splice items randomly from it:

    const arr = ["Q1", "Q2", "Q3", "Q4", "Q5", "Q6", "Q7", "Q8" ]; // simplified for demo
    
    const copy = arr.slice();
    
    const result = Array.from({length:5}, (_, i) => copy.splice(Math.random() * copy.length | 0, 1)[0]);
     
    console.log(result);

    You can actually do that with the original array if you don’t need it intact after the selection.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search