You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

多题库随机抽题组卷的JavaScript实现难题求助

在线考试系统随机抽题与功能实现方案

先解决你当前遇到的两个核心问题,再帮你实现后续需要的功能:

一、解决现有抽题问题

1. 修复randsplice导致的二维数组扁平化问题

你的randsplice方法返回的是splice的结果——一个包含被删除元素的数组,而不是单个题目元素。这会导致你push到newArray里的是嵌套数组,后续处理时容易扁平化,把题目和选项混为一谈。

修改randsplice方法,直接返回被删除的单个题目元素:

Array.prototype.randsplice = function() {
  var ri = Math.floor(Math.random() * this.length);
  // 取splice返回数组的第一个元素(因为我们只删了1个)
  var rs = this.splice(ri, 1)[0];
  return rs;
}

2. 解决randval重复抽题的问题

randval只是随机读取元素不删除,自然会重复。更优雅的方式是先洗牌再截取前N个,既不会重复,也不会修改原题库数组(方便后续复用):

// 给数组添加随机抽取n个不重复元素的方法
Array.prototype.sample = function(n) {
  // 先复制原数组,避免修改原题库
  const copy = [...this];
  // 用你已有的shuffle方法打乱
  copy.shuffle();
  // 取前n个元素
  return copy.slice(0, n);
}

然后简化你的抽题逻辑,不用那些冗余的newArraymyFunction

// 每个题库要抽取的题目数量
const pool1Count = 2;
const pool2Count = 2;

// 从两个题库抽题并合并
const selectedQuestions = [
  ...questions.sample(pool1Count),
  ...questions2.sample(pool2Count)
];

// 混排所有选中的题目
selectedQuestions.shuffle();

二、实现你需要的额外功能

1. 可开关的选项乱序(数值类自动排序)

需要先判断选项是否为数值,再决定是乱序还是排序,同时要同步更新正确答案的字母标识(因为选项位置变了):

// 判断选项是否全为数值
function areOptionsNumeric(question) {
  // 题目结构是[题干, 选项A, 选项B, 选项C, 正确答案],取选项部分
  const options = question.slice(1, 4);
  return options.every(opt => !isNaN(parseFloat(opt)) && isFinite(opt));
}

// 处理选项排序/乱序的核心函数
function handleOptions(question, enableShuffle) {
  if (!enableShuffle) return question;

  const [title, optA, optB, optC, correctLetter] = question;
  const options = [optA, optB, optC];
  // 获取正确选项的实际内容
  const correctValue = question[["A","B","C"].indexOf(correctLetter) + 1];

  let processedOptions;
  if (areOptionsNumeric(question)) {
    // 数值类选项从小到大排序
    processedOptions = [...options].sort((a, b) => parseFloat(a) - parseFloat(b));
  } else {
    // 非数值类选项乱序
    processedOptions = [...options].shuffle();
  }

  // 重新映射正确答案的字母
  const newCorrectIndex = processedOptions.findIndex(opt => opt === correctValue);
  const newCorrectLetter = ["A","B","C"][newCorrectIndex];

  return [title, ...processedOptions, newCorrectLetter];
}

// 使用示例:开启选项乱序
const enableOptionShuffle = true;
const finalQuestions = selectedQuestions.map(q => handleOptions(q, enableOptionShuffle));

2. 错题补救页面

需要在答题过程中记录错题,考试结束后渲染错题列表,支持重新作答:

// 存储错题的数组,包含题目和用户的错误答案
const wrongQuestions = [];

// 检查答案的函数,同时记录错题
function checkUserAnswer(question, userAnswer) {
  const correctAnswer = question[4];
  if (userAnswer === correctAnswer) {
    correct++;
    return true;
  } else {
    wrongQuestions.push({
      question: [...question], // 复制题目避免后续修改影响
      userAnswer: userAnswer
    });
    return false;
  }
}

// 渲染错题补救页面的函数
function renderWrongPage() {
  if (wrongQuestions.length === 0) {
    alert("太棒了!你没有错题😎");
    return;
  }

  let html = "<h3>错题补救</h3>";
  wrongQuestions.forEach((item, index) => {
    const q = item.question;
    html += `
      <div class="wrong-question">
        <p>${index+1}. ${q[0]}</p>
        <p>选项:A.${q[1]} B.${q[2]} C.${q[3]}</p>
        <p>你的答案:${item.userAnswer} | 正确答案:${q[4]}</p>
        <button onclick="retryQuestion(${index})">重新作答</button>
      </div>
    `;
  });
  document.getElementById("wrong-page").innerHTML = html;
}

// 重新作答的逻辑(示例)
function retryQuestion(index) {
  const item = wrongQuestions[index];
  // 这里可以弹出选择框让用户重新选答案,然后再次检查
  const newAnswer = prompt("请输入你的答案(A/B/C):");
  if (newAnswer === item.question[4]) {
    alert("答对了!");
    // 可以从错题数组中移除该题
    wrongQuestions.splice(index, 1);
    renderWrongPage();
  } else {
    alert("还是错了,再想想!");
  }
}

3. 分数统计功能

直接根据正确题数和总题数计算,支持百分比或分值制:

// 计算分数(支持自定义每题分值)
function calculateTotalScore(totalQuestions, correctAnswers, pointsPerQuestion = 1) {
  const totalPoints = totalQuestions * pointsPerQuestion;
  const earnedPoints = correctAnswers * pointsPerQuestion;
  const percentage = Math.round((earnedPoints / totalPoints) * 100);

  return {
    totalQuestions,
    correctAnswers,
    totalPoints,
    earnedPoints,
    percentage
  };
}

// 使用示例
const score = calculateTotalScore(selectedQuestions.length, correct);
alert(`考试结束!你的得分:${score.earnedPoints}/${score.totalPoints}(${score.percentage}%)`);

希望这些解决方案能帮你顺利完成项目,如果还有细节问题可以继续提问~

内容的提问来源于stack exchange,提问作者gwinnc

火山引擎 最新活动