如何从5个学科题库数组中各随机选取10道题构建在线测验?
解决方案:从多学科题库各随机抽取10道题
核心思路
先将题目按学科拆分为独立数组,通过通用函数从每个数组中随机抽取10道不重复题目,最后合并所有抽取的题目作为测验题库,同时保留你原有测验的交互逻辑。
1. 拆分题库为学科数组
把原有的单题库拆分为5个对应学科的数组,示例如下:
// 数学题库 const mathQuestions = [ { question: '2 + 2 = ?', choice1: '3', choice2: '4', choice3: '5', choice4: '6', answer: 2 }, // 补充剩余数学题... ]; // 科学题库 const scienceQuestions = [ { question: '水的化学式是?', choice1: 'H2O', choice2: 'CO2', choice3: 'O2', choice4: 'H2', answer: 1 }, // 补充剩余科学题... ]; // 语言题库 const languageQuestions = [ { question: '以下哪个是中文实词?', choice1: '的', choice2: '了', choice3: '猫', choice4: '吗', answer: 3 }, // 补充剩余语言题... ]; // 历史、地理题库同理 const historyQuestions = []; const geographyQuestions = [];
2. 编写随机抽题函数
实现一个通用函数,从任意题库数组中抽取指定数量的不重复题目:
// 从目标数组中随机抽取count道不重复题目 function getRandomQuestions(questionArray, count) { const tempArray = [...questionArray]; // 复制原数组避免修改源数据 const selected = []; for (let i = 0; i < count; i++) { const randomIndex = Math.floor(Math.random() * tempArray.length); selected.push(tempArray[randomIndex]); tempArray.splice(randomIndex, 1); // 移除已选题目,防止重复抽取 } return selected; }
3. 修改游戏初始化逻辑
更新startGame函数,从每个学科抽取10题并合并,同时打乱题目顺序:
let availableQuestions = []; // 调整总题数为50(5学科×10题) const MAX_QUESTIONS = 50; startGame = () => { questionCounter = 0; score = 0; // 从各学科抽取10题 const selectedMath = getRandomQuestions(mathQuestions, 10); const selectedScience = getRandomQuestions(scienceQuestions, 10); const selectedLanguage = getRandomQuestions(languageQuestions, 10); const selectedHistory = getRandomQuestions(historyQuestions, 10); const selectedGeography = getRandomQuestions(geographyQuestions, 10); // 合并所有题目并随机打乱顺序 availableQuestions = [ ...selectedMath, ...selectedScience, ...selectedLanguage, ...selectedHistory, ...selectedGeography ].sort(() => Math.random() - 0.5); getNewQuestion(); };
4. 完整修改后的game.js代码
const question = document.getElementById("question"); const choices = Array.from(document.getElementsByClassName("choice-text")); const questionCounterText = document.getElementById('questionCounter'); const scoreText = document.getElementById('score'); let currentQuestion = {}; let acceptingAnswers = false; let score = 0; let questionCounter = 0; let availableQuestions = []; // 各学科题库数组 const mathQuestions = [ { question: '2 + 2 = ?', choice1: '3', choice2: '4', choice3: '5', choice4: '6', answer: 2 }, // 补充更多数学题 ]; const scienceQuestions = [ { question: '水的化学式是?', choice1: 'H2O', choice2: 'CO2', choice3: 'O2', choice4: 'H2', answer: 1 }, // 补充更多科学题 ]; const languageQuestions = [ { question: '以下哪个是中文实词?', choice1: '的', choice2: '了', choice3: '猫', choice4: '吗', answer: 3 }, // 补充更多语言题 ]; const historyQuestions = []; const geographyQuestions = []; // 常量配置 const CORRECT_BONUS = 1; const MAX_QUESTIONS = 50; // 随机抽题函数 function getRandomQuestions(questionArray, count) { const tempArray = [...questionArray]; const selected = []; for (let i = 0; i < count; i++) { const randomIndex = Math.floor(Math.random() * tempArray.length); selected.push(tempArray[randomIndex]); tempArray.splice(randomIndex, 1); } return selected; } // 游戏初始化 startGame = () => { questionCounter = 0; score = 0; const selectedMath = getRandomQuestions(mathQuestions, 10); const selectedScience = getRandomQuestions(scienceQuestions, 10); const selectedLanguage = getRandomQuestions(languageQuestions, 10); const selectedHistory = getRandomQuestions(historyQuestions, 10); const selectedGeography = getRandomQuestions(geographyQuestions, 10); availableQuestions = [ ...selectedMath, ...selectedScience, ...selectedLanguage, ...selectedHistory, ...selectedGeography ].sort(() => Math.random() - 0.5); getNewQuestion(); }; // 获取新题目(原有逻辑不变) getNewQuestion = () => { if(availableQuestions.length === 0 || questionCounter >= MAX_QUESTIONS){ localStorage.setItem('mostRecentScore', score); return window.location.assign('/end.html'); } questionCounter++; questionCounterText.innerText = `${questionCounter}/${MAX_QUESTIONS}`; const questionIndex = Math.floor(Math.random() * availableQuestions.length); currentQuestion = availableQuestions[questionIndex]; question.innerText = currentQuestion.question; choices.forEach(choice => { const number = choice.dataset['number']; choice.innerText = currentQuestion['choice' + number]; }); availableQuestions.splice(questionIndex, 1); acceptingAnswers = true; }; // 答题事件监听(原有逻辑不变) choices.forEach(choice =>{ choice.addEventListener('click', e =>{ if(!acceptingAnswers) return; acceptingAnswers = false; const selectedChoice = e.target; const selectedAnswer = selectedChoice.dataset['number']; const classToApply = selectedAnswer == currentQuestion.answer ? "correct" : "incorrect"; if(classToApply === 'correct'){ incrementScore(CORRECT_BONUS); } selectedChoice.parentElement.classList.add(classToApply); setTimeout (() => { selectedChoice.parentElement.classList.remove(classToApply); getNewQuestion(); }, 1000); }); }); // 计分逻辑(原有逻辑不变) incrementScore = num =>{ score += num; scoreText.innerText = score; } startGame();
关键说明
- 题库拆分:按学科分类管理题目,便于后续维护和扩展
- 抽题逻辑:通过复制数组+移除已选元素的方式,确保每道题只会被抽取一次
- 顺序打乱:合并题目后随机排序,避免测验中题目集中在同一学科
- 兼容原有代码:保留了你原有的答题、计分、跳转逻辑,无需额外修改HTML文件
内容的提问来源于stack exchange,提问作者Dony Peter Puthumana
相关产品推荐
相关产品推荐

