使用jquery基于数组对象计算分数



我是JavaScript的初学者,我想做一个测验,计算数组中对象(类型)的分数。所以总分应该计算用户在每个部分的得分(例如:数学2/2,科学1/2)。总= 3/4)。有没有可能用jquery实现呢?请帮帮我,谢谢。

var all_questions = [{
type:"math",
question_string: "4 + 4",
choices: {
correct: "8",
wrong: ["2", "3", "9"]
}
}, {
type:"math",
question_string: "4 * 4",
choices: {
correct: "16",
wrong: ["24", "13", "4"]
}
}, {
type:"sience",
question_string: "What part of the body helps you move?",
choices: {
correct: "Muscles",
wrong: ["Eyes", "Pancreas", "Lungs"]
}
}, {
type:"sience",
question_string: 'What star shines in the day and provides light?',
choices: {
correct: "Sun",
wrong: ["Moon", "Venus", "Mars"]
}
}];
var Quiz = function(quiz_name) {
this.quiz_name = quiz_name;
this.questions = [];
}
Quiz.prototype.add_question = function(question) {
var index_to_add_question = Math.floor(Math.random() * this.questions.length);
this.questions.splice(index_to_add_question, 0, question);
}
Quiz.prototype.render = function(container) {
var self = this;
$('#quiz-results').hide();
$('#quiz-name').text(this.quiz_name);
var question_container = $('<div>').attr('id', 'question').insertAfter('#quiz-name');
function change_question() {
self.questions[current_question_index].render(question_container);
$('#prev-question-button').prop('disabled', current_question_index === 0);
$('#next-question-button').prop('disabled', current_question_index === self.questions.length - 1);
var all_questions_answered = true;
for (var i = 0; i < self.questions.length; i++) {
if (self.questions[i].user_choice_index === null) {
all_questions_answered = false;
break;
}
}
$('#submit-button').prop('disabled', !all_questions_answered);
}
var current_question_index = 0;
change_question();
$('#prev-question-button').click(function() {
if (current_question_index > 0) {
current_question_index--;
change_question();
}
});

$('#next-question-button').click(function() {
if (current_question_index < self.questions.length - 1) {
current_question_index++;
change_question();
}
});
$('#submit-button').click(function() {
var score = 0;
for (var i = 0; i < self.questions.length; i++) {
if (self.questions[i].user_choice_index === self.questions[i].correct_choice_index) {
score++;
}
}
var percentage = score / self.questions.length;
console.log(percentage);
var message;
if (percentage === 1) {
message = 'Great job!'
} else if (percentage >= .75) {
message = 'You did alright.'
} else if (percentage >= .5) {
message = 'Better luck next time.'
} else {
message = 'Maybe you should try a little harder.'
}
$('#quiz-results-message').text(message);
$('#quiz-results-score').html('You got <b>' + score + '/' + self.questions.length + '</b> questions correct.');
$('#quiz-results').slideDown();
$('#quiz button').slideUp();
});
question_container.bind('user-select-change', function() {
var all_questions_answered = true;
for (var i = 0; i < self.questions.length; i++) {
if (self.questions[i].user_choice_index === null) {
all_questions_answered = false;
break;
}
}
$('#submit-button').prop('disabled', !all_questions_answered);
});
}
var Question = function(question_string, correct_choice, wrong_choices) {
// Private fields for an instance of a Question object.
this.question_string = question_string;
this.choices = [];
this.user_choice_index = null; // Index of the user's choice selection

// Random assign the correct choice an index
this.correct_choice_index = Math.floor(Math.random() * wrong_choices.length + 1);
// Fill in this.choices with the choices
var number_of_choices = wrong_choices.length + 1;
for (var i = 0; i < number_of_choices; i++) {
if (i === this.correct_choice_index) {
this.choices[i] = correct_choice;
} else {
// Randomly pick a wrong choice to put in this index
var wrong_choice_index = Math.floor(Math.random(0, wrong_choices.length));
this.choices[i] = wrong_choices[wrong_choice_index];

// Remove the wrong choice from the wrong choice array so that we don't pick it again
wrong_choices.splice(wrong_choice_index, 1);
}
}
}
Question.prototype.render = function(container) {
var self = this;

var question_string_h2;
if (container.children('h2').length === 0) {
question_string_h2 = $('<h2>').appendTo(container);
} else {
question_string_h2 = container.children('h2').first();
}
question_string_h2.text(this.question_string);

if (container.children('input[type=radio]').length > 0) {
container.children('input[type=radio]').each(function() {
var radio_button_id = $(this).attr('id');
$(this).remove();
container.children('label[for=' + radio_button_id + ']').remove();
});
}
for (var i = 0; i < this.choices.length; i++) {
var choice_radio_button = $('<input>')
.attr('id', 'choices-' + i)
.attr('type', 'radio')
.attr('name', 'choices')
.attr('value', 'choices-' + i)
.attr('checked', i === this.user_choice_index)
.appendTo(container);

var choice_label = $('<label>')
.text(this.choices[i])
.attr('for', 'choices-' + i)
.appendTo(container);
}


$('input[name=choices]').change(function(index) {
var selected_radio_button_value = $('input[name=choices]:checked').val();


self.user_choice_index = parseInt(selected_radio_button_value.substr(selected_radio_button_value.length - 1, 1));


container.trigger('user-select-change');
});
}

$(document).ready(function() {
var quiz = new Quiz('');

for (var i = 0; i < all_questions.length; i++) {
var question = new Question(all_questions[i].question_string, all_questions[i].choices.correct, all_questions[i].choices.wrong);
quiz.add_question(question);
}
var quiz_container = $('#quiz');
quiz.render(quiz_container);
});
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<title>CodePen - Multiple Choice Quiz</title>
<link rel="stylesheet" href="./style.css">
</head>
<body>
<!-- partial:index.partial.html -->
<div id="quiz">
<h1 id="quiz-name"></h1>
<button id="submit-button">Submit</button>
<button id="next-question-button">Next</button>
<button id="prev-question-button">Back</button>

<div id="quiz-results">
<p id="quiz-results-message"></p>
<p id="quiz-results-score"></p>
</div>
</div>
<!-- partial -->
<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script><script  src="./script.js"></script>
</body>
</html>

基本上您正在寻找group by逻辑-您希望按问题类型对答案进行分组。为了解决这个问题:

  1. question_type添加到Question(不是强制的,我们可以从原始问题数组中取。为了便于阅读,我会保留它)。
  2. 为了实现group by逻辑,我们可以reduce过滤正确的答案和转换Questions数组放入乐谱字典中。键是问题类型,值是分数。对于每一个正确答案,如果类别已经存在,我们就加1,如果不存在,我们就初始化为1。
    我使用的是一个更短的版本,但效果完全相同:
acc.set(curr.question_type, (acc.get(curr.question_type) || 0) + 1);
//     |-- add / update --|  |- current score if exists -| 0 if not, plus one

这是完整的reduce

// global counter for total answers
let totalScore = 0;
const result = a.reduce((acc, curr) => {
// if it's the right answer
if (curr.user_choice_index === curr.correct_choice_index) {
// add / update the entity with 1 if's the first right answer in the category so far or add 1 if it exists
acc.set(curr.question_type, (acc.get(curr.question_type) || 0) + 1);
totalScore++;
}
return acc;
}, new Map());
第二部分是渲染结果:
// convert the Map back to array
const scoreText = Array.from(score.entries())
// render each type in a different line     
.map(([type, scoreByType]) => `<b>${type}</b>: ${scoreByType}`)
.join('<br />');

阅读更多关于

  • map . entry
  • Array.from
  • Array.reduce

完整的工作示例:

var all_questions = [{
type:"math",
question_string: "4 + 4",
choices: {
correct: "8",
wrong: ["2", "3", "9"]
}
}, {
type:"math",
question_string: "4 * 4",
choices: {
correct: "16",
wrong: ["24", "13", "4"]
}
}, {
type:"sience",
question_string: "What part of the body helps you move?",
choices: {
correct: "Muscles",
wrong: ["Eyes", "Pancreas", "Lungs"]
}
}, {
type:"sience",
question_string: 'What star shines in the day and provides light?',
choices: {
correct: "Sun",
wrong: ["Moon", "Venus", "Mars"]
}
}];
var Quiz = function(quiz_name) {
this.quiz_name = quiz_name;
this.questions = [];
}
Quiz.prototype.add_question = function(question) {
var index_to_add_question = Math.floor(Math.random() * this.questions.length);
this.questions.splice(index_to_add_question, 0, question);
}
Quiz.prototype.render = function(container) {
var self = this;
$('#quiz-results').hide();
$('#quiz-name').text(this.quiz_name);
var question_container = $('<div>').attr('id', 'question').insertAfter('#quiz-name');
function change_question() {
self.questions[current_question_index].render(question_container);
$('#prev-question-button').prop('disabled', current_question_index === 0);
$('#next-question-button').prop('disabled', current_question_index === self.questions.length - 1);
var all_questions_answered = true;
for (var i = 0; i < self.questions.length; i++) {
if (self.questions[i].user_choice_index === null) {
all_questions_answered = false;
break;
}
}
$('#submit-button').prop('disabled', !all_questions_answered);
}
var current_question_index = 0;
change_question();
$('#prev-question-button').click(function() {
if (current_question_index > 0) {
current_question_index--;
change_question();
}
});

$('#next-question-button').click(function() {
if (current_question_index < self.questions.length - 1) {
current_question_index++;
change_question();
}
});
$('#submit-button').click(function() {
let totalScore = 0;
const score = self.questions.reduce((acc, curr) => {
if (curr.user_choice_index === curr.correct_choice_index) {
acc.set(curr.question_type, (acc.get(curr.question_type) || 0) + 1);
totalScore++;
}
return acc;
}, new Map());
var percentage = score / self.questions.length;
console.log(percentage);
var message;
if (percentage === 1) {
message = 'Great job!'
} else if (percentage >= .75) {
message = 'You did alright.'
} else if (percentage >= .5) {
message = 'Better luck next time.'
} else {
message = 'Maybe you should try a little harder.'
}
$('#quiz-results-message').text(message);
const scoreText = Array.from(score.entries())
.map(([type, scoreByType]) => `<b>${type}</b>: ${scoreByType}`)
.join('n');
$('#quiz-results-score').html('You got <b>' + totalScore + '/' + self.questions.length + '</b> questions correct.n' + scoreText);
$('#quiz-results').slideDown();
$('#quiz button').slideUp();
});
question_container.bind('user-select-change', function() {
var all_questions_answered = true;
for (var i = 0; i < self.questions.length; i++) {
if (self.questions[i].user_choice_index === null) {
all_questions_answered = false;
break;
}
}
$('#submit-button').prop('disabled', !all_questions_answered);
});
}
var Question = function(question_string, correct_choice, wrong_choices, question_type) {
// Private fields for an instance of a Question object.
this.question_string = question_string;
this.question_type = question_type;
this.choices = [];
this.user_choice_index = null; // Index of the user's choice selection

// Random assign the correct choice an index
this.correct_choice_index = Math.floor(Math.random() * wrong_choices.length + 1);
// Fill in this.choices with the choices
var number_of_choices = wrong_choices.length + 1;
for (var i = 0; i < number_of_choices; i++) {
if (i === this.correct_choice_index) {
this.choices[i] = correct_choice;
} else {
// Randomly pick a wrong choice to put in this index
var wrong_choice_index = Math.floor(Math.random(0, wrong_choices.length));
this.choices[i] = wrong_choices[wrong_choice_index];

// Remove the wrong choice from the wrong choice array so that we don't pick it again
wrong_choices.splice(wrong_choice_index, 1);
}
}
}
Question.prototype.render = function(container) {
var self = this;

var question_string_h2;
if (container.children('h2').length === 0) {
question_string_h2 = $('<h2>').appendTo(container);
} else {
question_string_h2 = container.children('h2').first();
}
question_string_h2.text(this.question_string);

if (container.children('input[type=radio]').length > 0) {
container.children('input[type=radio]').each(function() {
var radio_button_id = $(this).attr('id');
$(this).remove();
container.children('label[for=' + radio_button_id + ']').remove();
});
}
for (var i = 0; i < this.choices.length; i++) {
var choice_radio_button = $('<input>')
.attr('id', 'choices-' + i)
.attr('type', 'radio')
.attr('name', 'choices')
.attr('value', 'choices-' + i)
.attr('checked', i === this.user_choice_index)
.appendTo(container);

var choice_label = $('<label>')
.text(this.choices[i])
.attr('for', 'choices-' + i)
.appendTo(container);
}


$('input[name=choices]').change(function(index) {
var selected_radio_button_value = $('input[name=choices]:checked').val();


self.user_choice_index = parseInt(selected_radio_button_value.substr(selected_radio_button_value.length - 1, 1));


container.trigger('user-select-change');
});
}

$(document).ready(function() {
var quiz = new Quiz('');

for (var i = 0; i < all_questions.length; i++) {
var question = new Question(all_questions[i].question_string, all_questions[i].choices.correct, all_questions[i].choices.wrong, all_questions[i].type);
quiz.add_question(question);
}
var quiz_container = $('#quiz');
quiz.render(quiz_container);
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CodePen - Multiple Choice Quiz</title>
<link rel="stylesheet" href="./style.css">
</head>
<body>
<!-- partial:index.partial.html -->
<div id="quiz">
<h1 id="quiz-name"></h1>
<button id="submit-button">Submit</button>
<button id="next-question-button">Next</button>
<button id="prev-question-button">Back</button>
<div id="quiz-results">
<p id="quiz-results-message"></p>
<p id="quiz-results-score"></p>
</div>
</div>
<!-- partial -->
<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>
<script src="./script.js"></script>
</body>
</html>

最新更新