简体   繁体   中英

how to use forEach() on nested objects in an array

I'm working on a browser quiz project. I have made an array of objects that has the question choices nested in a further object. I'm struggling to figure out how to compare the users choice of the 4 options to the correct answer in the answers array.

I'm stuck because I don't know how to use for each on nested objects inside an array.

const list = document.createElement('ol');
const li1 = document.createElement('li');
const li2 = document.createElement('li');
const li3 = document.createElement('li');
const li4 = document.createElement('li');

const choices = document.querySelector('.choices');

choices.appendChild(list);
list.appendChild(li1);
list.appendChild(li2);
list.appendChild(li3);
list.appendChild(li4);

const possibleAnswers = ['1', '2', '3', '4', '5', '6', '7'];

const questionPool = [
    {
        questionOne:
            {
                answers:
                    {
                        answerOne: li1,
                        answerTwo: li2,
                        answerThree: li3,
                        answerFour: li4
                    }
            }
    },
    {
        questionTwo:
            {
                answers:
                    {
                        answerOne: li1,
                        answerTwo: li2,
                        answerThree: li3,
                        answerFour: li4
                    }
            }
    },
    {
        questionThree:
            {
                answers:
                    {
                        answerOne: li1,
                        answerTwo: li2,
                        answerThree: li3,
                        answerFour: li4
                    }
            }
    },
    {
        questionFour:
            {
                answers:
                    {
                        answerOne: li1,
                        answerTwo: li2,
                        answerThree: li3,
                        answerFour: li4
                    }
            }
    },
    {
        questionFive:
            {
                answers:
                    {
                        answerOne: li1,
                        answerTwo: li2,
                        answerThree: li3,
                        answerFour: li4
                    }
            }
    },
    {
        questionSix:
            {
                answers:
                    {
                        answerOne: li1,
                        answerTwo: li2,
                        answerThree: li3,
                        answerFour: li4
                    }
            }
    },
    {
        questionSeven:
            {
                answers:
                    {
                        answerOne: li1,
                        answerTwo: li2,
                        answerThree: li3,
                        answerFour: li4
                    }
            }
    }
];

If I understood your question correctly I think this answer might help you;

  1. You have to change the structure of your object to make it universal.
  2. You can go through your object array in which each object refers to the object of the 4 answers.
  3. Loop to access the 4 possible answers.

This is how I would do it:

var list = document.createElement("ol");
        var li1 = document.createElement("li");
        var li2 = document.createElement("li");
        var li3 = document.createElement("li");
        var li4 = document.createElement("li");

        let choices = document.querySelector(".choices")

        choices.appendChild(list)
        list.appendChild(li1)
        list.appendChild(li2)
        list.appendChild(li3)
        list.appendChild(li4)

        let questionPool = [
            {
                answers: {
                    1: li1,
                    2: li2,
                    3: li3,
                    4: li4
                }
            },
            {
                answers: {
                    1: li1,
                    2: li2,
                    3: li3,
                    4: li4
                }
            },
            {
                answers: {
                    1: li1,
                    2: li2,
                    3: li3,
                    4: li4
                }
            }
        ];

        questionPool.forEach(element => {
            for(const item in element.answers){
                //here you have access to the 4 li
                console.log(element.answers[item]);
            }
        });

I tried to refactor your code beacause most of it was repetitions for no reason, more details in the comments:

 const questionEl = document.createElement('span') const list = document.createElement("ol"); const nextBtn = document.createElement('button') const choicesEl = document.querySelector(".choices") nextBtn.textContent = 'Next' choicesEl.appendChild(questionEl) choicesEl.appendChild(list) choicesEl.appendChild(nextBtn) // Store you list elements by span (text of the answer) and radio (input field) const listElements = Array.from({ length: 4 }).map(i => { const li = document.createElement('li') const radio = document.createElement('input') const span = document.createElement('span') radio.type = 'radio' radio.name = 'quiz-radio' li.appendChild(radio) li.appendChild(span) list.appendChild(li) // for convenience span.onclick = () => radio.click() return { radio, span } }) // use arrays instead of objects const questionsPool = [ { question: 'What is the formula for water?', right: 0, answers: [ 'H2O', 'NH3', 'CO2', 'C6H12O6', ] }, { question: 'What color is the sky?', right: 1, answers: [ 'blue', 'skyblue', 'lightblue', 'navyblue', ] } ] let score = 0 let questionIndex = 0 // update the texts in the spans const updateQuestion = () => { const { question, answers } = questionsPool[questionIndex] questionEl.textContent = question for (let i = 0; i < 4; i++) listElements[i].span.textContent = answers[i] } // inital rendering updateQuestion() nextBtn.onclick = () => { // if the user selected the right answer: increment his score if (listElements[questionsPool[questionIndex].right].radio.checked) score++ // if there is remaining question if (questionIndex + 1 < questionsPool.length) { // go to the next one and update texts questionIndex++ updateQuestion() } else // show the final user score console.log({ score }) }
 <div class="choices"></div>

Hope it helped you !

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM