2
\$\begingroup\$

I'm trying to realize simple testing application. And I ran into a problem. I have two arrays. The first is an array with the initial questions, the second array is the answers of users. And now I need to count the number of correct answers. I wrote the following code. I wonder: how optimal is it and, if it's bad, how to optimize it? I tried to change the "filter" to "find", but this did not affect the execution time of the code.

const questions = [
	{
		questionId: 1,
		question: 'question?',
		answers: [
			{ value: '1', right: true },
			{ value: '2', right: false },
			{ value: '3', right: false },
			{ value: '4', right: false },
		],
	},
	{
		questionId: 2,
		question: 'question?',
		answers: [
			{ value: '1', right: false },
			{ value: '2', right: false },
			{ value: '3', right: false },
			{ value: '4', right: true },
		],
	},
	{
		questionId: 3,
		question: 'question?',
		answers: [
			{ value: '1', right: false },
			{ value: '2', right: true },
			{ value: '3', right: false },
			{ value: '4', right: false },
		],
	},
	{
		questionId: 4,
		question: 'question?',
		answers: [
			{ value: '1', right: true },
			{ value: '2', right: false },
			{ value: '3', right: false },
			{ value: '4', right: false },
		],
	},
	{
		questionId: 5,
		question: 'question?',
		answers: [
			{ value: '1', right: false },
			{ value: '2', right: false },
			{ value: '3', right: true },
			{ value: '4', right: false },
		],
	},
]

const answersFromUser = [
	{
		questionId: 1,
		value: '1',
	},
	{
		questionId: 2,
		value: '1',
	},
	{
		questionId: 3,
		value: '1',
	},
	{
		questionId: 4,
		value: '1',
	},
	{
		questionId: 5,
		value: '1',
	},
]

const createObj = (questionId, value, right) => {
	return { questionId, value, right }
}

const checkAnswers = (questionsArr, answersArr) => {
	return answersArr.map(answer => {
		const currentQuestion = questionsArr.filter(
			question => question.questionId === answer.questionId
		)

		const currentAnswer = currentQuestion[0].answers.filter(
			answerInCurrentQuestion => answerInCurrentQuestion.value === answer.value
		)[0]

		return createObj(
			answer.questionId,
			currentAnswer.value,
			currentAnswer.right
		)
	})
}

const countRightAnswers = answers => {
	return answers.filter(answer => answer.right).length
}

const countWrongAnswers = answers => {
	return answers.filter(answer => !answer.right).length
}

console.log(checkAnswers(questions, answersFromUser))
console.log("Right Answers " + countRightAnswers(checkAnswers(questions, answersFromUser)))
console.log("Wrong Answers " + countWrongAnswers(checkAnswers(questions, answersFromUser)))

\$\endgroup\$
2
  • \$\begingroup\$ Can there ever be more than one correct answer for a question? Do you need all the info in the answer objects you create? You could make things a lot simpler if you just had an array for correct answers and another for the user's answers. \$\endgroup\$
    – JollyJoker
    Commented Dec 13, 2019 at 12:31
  • 1
    \$\begingroup\$ No, there can only be one correct answer. No, not all information. Need a answer number and know whether it is correct or not. \$\endgroup\$ Commented Dec 13, 2019 at 13:14

1 Answer 1

1
\$\begingroup\$

This is not much of a code review answer, but I don't have time for more right now :(

Here's a stripped down version using only arrays for answers, with indexes (zero to four) as the question numbers. Essentially, it seems like much of your object structures aren't needed at all.

const correctAnswers = [1,4,2,1,3]

const userAnswers = [1,1,1,1,1]

const countRightAnswers = answers => answers.filter((a, i) => a == correctAnswers[i]).length

const indexOfRightAnswers = answers => answers.map((a, i) => a == correctAnswers[i] ? i : -1).filter(i => i > -1)

console.log(countRightAnswers(userAnswers))
console.log(indexOfRightAnswers(userAnswers))

Try it online!

\$\endgroup\$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.