Javascript比较两个复杂的对象

时间:2020-06-28 05:56:08

标签: javascript reactjs react-hooks use-effect

我正在对一个考试应用进行反应。我有两个数组,一个是用户给出的答案,另一个是正确答案。比较它们不会显示正确的结果。我正在使用挂钩,并且代码在useEffect挂钩内。结果也没有显示正确的问题数。

questions = [
{Qid: 1, Question: "This is question 1",
     Answers:[{Ans1:"Answer1",IsCorrect:true}
          {Ans2:"Answer2",IsCorrect:false}
          {Ans3:"Answer3",IsCorrect:false}
          {Ans4:"Answer4",IsCorrect:false}]},
{Qid: 2, Question: "This is question 2",
     Answers:[{Ans1:"Answer1",IsCorrect:false}
          {Ans2:"Answer2",IsCorrect:true}
          {Ans3:"Answer3",IsCorrect:false}
          {Ans4:"Answer4",IsCorrect:false}]},
{Qid: 3, Question: "This is question 3",
     Answers:[{Ans1:"Answer1",IsCorrect:true}
          {Ans2:"Answer2",IsCorrect:false}
          {Ans3:"Answer3",IsCorrect:false}
          {Ans4:"Answer4",IsCorrect:false}]},
{Qid: 4, Question: "This is question 4",
     Answers:[{Ans1:"Answer1",IsCorrect:false}
          {Ans2:"Answer2",IsCorrect:false}
          {Ans3:"Answer3",IsCorrect:true}
          {Ans4:"Answer4",IsCorrect:false}]}
]


keyquestions = [
{Qid: 1, Question: "This is question 1",
     Answers:[{Ans1:"Answer1",IsCorrect:false}
          {Ans2:"Answer2",IsCorrect:true}
          {Ans3:"Answer3",IsCorrect:false}
          {Ans4:"Answer4",IsCorrect:false}]},
{Qid: 2, Question: "This is question 2",
     Answers:[{Ans1:"Answer1",IsCorrect:false}
          {Ans2:"Answer2",IsCorrect:true}
          {Ans3:"Answer3",IsCorrect:false}
          {Ans4:"Answer4",IsCorrect:false}]},
{Qid: 3, Question: "This is question 3",
     Answers:[{Ans1:"Answer1",IsCorrect:true}
          {Ans2:"Answer2",IsCorrect:false}
          {Ans3:"Answer3",IsCorrect:false}
          {Ans4:"Answer4",IsCorrect:false}]},
{Qid: 4, Question: "This is question 4",
     Answers:[{Ans1:"Answer1",IsCorrect:false}
          {Ans2:"Answer2",IsCorrect:true}
          {Ans3:"Answer3",IsCorrect:false}
          {Ans4:"Answer4",IsCorrect:false}]}
]

我正在使用react钩子,组件的代码是

const Results = (props) => {

const [questions, setQuestions] = useState(props.quest);
const [keyq, setKey] = useState(props.keyq);
const [correctAnswers, setCorAns] = useState(0);
const [wrongAnswers, setWrong] = useState(0);
const [once, setOnce] = useState(true);

useEffect(() => {

    if(once){
    for (let index = 0; index < questions.length; index++) {
        var qa = questions[index].Answers;
        var ka = keyq[index].Answers;

        var k = JSON.stringify(ka);
        var q = JSON.stringify(qa);

        if (k === q) {
            var cor = correctAnswers;
            cor = cor + 1;
            setCorAns(cor)
        } else {
            var wr = wrongAnswers;
            wr = wr + 1;
            setWrong(wr + 1)
        }
    }
}
setOnce(false);

},[correctAnswers,keyq,questions,wrongAnswers,once])

return (
        <div>
            <h4>Right: {correctAnswers}</h4>
            <h4>Wrong: {wrongAnswers}</h4>
            </div>
    )
    }
    
    export default Results

3 个答案:

答案 0 :(得分:0)

您可以在此处应用filter,一种解决方案是找到索引并匹配,如果两者相同,则答案是true,另一种解决方案是在答案上应用every并检查是否isCorrect值与问题相同,如果相同则表示true,否则表示false。这是一个有效的示例。

var questions = [{Qid: 1, Question: "This is question 1", Answers:[{Ans1:"Answer1",IsCorrect:true}, {Ans2:"Answer2",IsCorrect:false}, {Ans3:"Answer3",IsCorrect:false}, {Ans4:"Answer4",IsCorrect:false}]},{Qid: 2, Question: "This is question 2", Answers:[{Ans1:"Answer1",IsCorrect:false}, {Ans2:"Answer2",IsCorrect:true}, {Ans3:"Answer3",IsCorrect:false}, {Ans4:"Answer4",IsCorrect:false}]},{Qid: 3, Question: "This is question 3", Answers:[{Ans1:"Answer1",IsCorrect:true}, {Ans2:"Answer2",IsCorrect:false}, {Ans3:"Answer3",IsCorrect:false}, {Ans4:"Answer4",IsCorrect:false}]},{Qid: 4, Question: "This is question 4", Answers:[{Ans1:"Answer1",IsCorrect:false}, {Ans2:"Answer2",IsCorrect:false}, {Ans3:"Answer3",IsCorrect:true}, {Ans4:"Answer4",IsCorrect:false}]}];
var keyquestions = [{Qid: 1, Question: "This is question 1", Answers:[{Ans1:"Answer1",IsCorrect:false}, {Ans2:"Answer2",IsCorrect:true}, {Ans3:"Answer3",IsCorrect:false}, {Ans4:"Answer4",IsCorrect:false}]},{Qid: 2, Question: "This is question 2", Answers:[{Ans1:"Answer1",IsCorrect:false}, {Ans2:"Answer2",IsCorrect:true}, {Ans3:"Answer3",IsCorrect:false}, {Ans4:"Answer4",IsCorrect:false}]},{Qid: 3, Question: "This is question 3", Answers:[{Ans1:"Answer1",IsCorrect:true}, {Ans2:"Answer2",IsCorrect:false}, {Ans3:"Answer3",IsCorrect:false}, {Ans4:"Answer4",IsCorrect:false}]},{Qid: 4, Question: "This is question 4", Answers:[{Ans1:"Answer1",IsCorrect:false}, {Ans2:"Answer2",IsCorrect:true}, {Ans3:"Answer3",IsCorrect:false}, {Ans4:"Answer4",IsCorrect:false}]}];

var result = questions.filter(k=>keyquestions.find(p=>p.Qid==k.Qid && p.Answers.findIndex(l=>l.IsCorrect)==k.Answers.findIndex(m=>m.IsCorrect))).length;

var result2 = questions.filter(k=>keyquestions.find(p=>p.Qid==k.Qid && p.Answers.every((l,i)=>l.IsCorrect==k.Answers[i].IsCorrect))).length;

console.log(`Total Correct answers are : ${result}`);
console.log(`Total Correct answers are : ${result2}`);

我希望这会有所帮助。

答案 1 :(得分:0)

尝试一下。但是如果您可以更改数据结构,那就更好了。您是否真的需要使用Ans1, Ans2, Ans3作为密钥?您可以像{Ans:"Answer4",IsCorrect:false}这样来做。如果您不能这样做,则下面的代码应该可以工作

import React, {useState, useEffect} from "react";
import "./styles.css";

const quest = [] // user_ans

const keyquest = [] // marking scheme

export default function App() {
  const [questions, setQuestions] = useState(quest);
  const [keyq, setKey] = useState(keyquest);
  const [correctAnswers, setCorAns] = useState(0);
  const [wrongAnswers, setWrong] = useState(0);
  const [once, setOnce] = useState(true);

  useEffect(() => {
    if(once) {
      keyq.map(q => {
        const user_q = questions.filter(user_q => user_q.Qid === q.Qid);

        // Get the correct answer of the question
        const marking_scheme_ans = q.Answers.filter(ans => ans.IsCorrect);
        const user_ans = user_q[0].Answers.filter(ans => ans.IsCorrect);
        
       // Because you used different keys for 4 answers as `ans1, ans2, ans3, ans4`
        const correct_answer_keys = Object.keys(marking_scheme_ans[0]).filter(key => key !== 'IsCorrect');
        const user_ans_keys = Object.keys(user_ans[0]).filter(key => key !== 'IsCorrect');;

        if(correct_answer_keys[0] === user_ans_keys[0]) {
          return setCorAns(c => c+1);
        } else {
          return setWrong(w => w +1);
        }
          
      })
    }
  }, [keyq,questions,once])

  return (
    <div>
        <h4>Right: {correctAnswers}</h4>
        <h4>Wrong: {wrongAnswers}</h4>
    </div>
  )
}

答案 2 :(得分:0)

我已经根据您提供的输入及其工作情况进行了比较。

但是我建议对您的答案数组和问题数组进行一些结构性更改,以提高性能。这种结构可帮助您轻松扩展系统。

  1. 答案数组的结构应如下所示

    [{ "Qid": 1, "answer" : "user selected answer"}, { "Qid": 2, "answer" : "user selected answer"}]

  2. 问题数组应如下所示

     [{Qid: 1, Question: "This is question 1",
    Answers:[{"option":"Answer1",IsCorrect:false}, 
       {"option":"Answer2",IsCorrect:true},{"option":"Answer3",IsCorrect:false}
       {"option":"Answer4",IsCorrect:false}]}]
    

let userAnswers = [{Qid: 1, Question: "This is question 1", Answers:[{Ans1:"Answer1",IsCorrect:false}, {Ans2:"Answer2",IsCorrect:false}, {Ans3:"Answer3",IsCorrect:false}, {Ans4:"Answer4",IsCorrect:false}]},{Qid: 2, Question: "This is question 2", Answers:[{Ans1:"Answer1",IsCorrect:false}, {Ans2:"Answer2",IsCorrect:true}, {Ans3:"Answer3",IsCorrect:false}, {Ans4:"Answer4",IsCorrect:false}]},{Qid: 3, Question: "This is question 3", Answers:[{Ans1:"Answer1",IsCorrect:true}, {Ans2:"Answer2",IsCorrect:false}, {Ans3:"Answer3",IsCorrect:false}, {Ans4:"Answer4",IsCorrect:false}]},{Qid: 4, Question: "This is question 4", Answers:[{Ans1:"Answer1",IsCorrect:false}, {Ans2:"Answer2",IsCorrect:false}, {Ans3:"Answer3",IsCorrect:true}, {Ans4:"Answer4",IsCorrect:false}]}];


let keyquestions = [{Qid: 1, Question: "This is question 1", Answers:[{Ans1:"Answer1",IsCorrect:false}, {Ans2:"Answer2",IsCorrect:true}, {Ans3:"Answer3",IsCorrect:false}, {Ans4:"Answer4",IsCorrect:false}]},{Qid: 2, Question: "This is question 2", Answers:[{Ans1:"Answer1",IsCorrect:false}, {Ans2:"Answer2",IsCorrect:true}, {Ans3:"Answer3",IsCorrect:false}, {Ans4:"Answer4",IsCorrect:false}]},{Qid: 3, Question: "This is question 3", Answers:[{Ans1:"Answer1",IsCorrect:true}, {Ans2:"Answer2",IsCorrect:false}, {Ans3:"Answer3",IsCorrect:false}, {Ans4:"Answer4",IsCorrect:false}]},{Qid: 4, Question: "This is question 4", Answers:[{Ans1:"Answer1",IsCorrect:false}, {Ans2:"Answer2",IsCorrect:true}, {Ans3:"Answer3",IsCorrect:false}, {Ans4:"Answer4",IsCorrect:false}]}];
let result = {
"right" : 0, "wrong" : 0, "unattempted" :0
};


result = userAnswers.reduce((res, i) => {
  let user = i.Answers.filter(a =>  !!a.IsCorrect);
  let question = keyquestions.filter(k => k.Qid == i.Qid)[0];
  let actualAnswer = question.Answers.filter(a =>  !!a.IsCorrect)[0];
  if(!!user && user.length) {
  user[Object.keys(user)[0]] == actualAnswer[Object.keys(actualAnswer)[0]] ? res.right++ : res.wrong++;
  } else {
    res.unattempted++;
  }
  return res;
}, result);

console.log(result);