0

0

JavaScript 实现题目、选项与答案的随机化生成(去重+答案位置随机)

花韻仙語

花韻仙語

发布时间:2026-02-10 20:22:09

|

170人浏览过

|

来源于php中文网

原创

JavaScript 实现题目、选项与答案的随机化生成(去重+答案位置随机)

本文提供一种健壮、可扩展的 javascript 方法,用于从任意长度的原始列表中为每道题自动生成唯一且随机排序的 4 个选项(含正确答案),确保无重复、答案位置随机,并输出标准化的 `question` 对象代码。

在构建交互式测验、教育类应用或自动化题库生成工具时,一个常见需求是:基于一组原始素材(如图片路径、名词列表等),为每个条目动态生成一道单选题,包含题干、4 个互不重复的选项,且正确答案必须随机分布在 A/B/C/D 四个位置之一。原始实现依赖大量 replace() 字符串操作,逻辑耦合高、难以维护,且无法保证选项唯一性与答案位置随机性——尤其在输入列表远大于 4 项时易出错。

以下方案采用函数式与数组操作思想重构,核心策略包括:

因赛AIGC
因赛AIGC

因赛AIGC解决营销全链路应用场景

下载
  • 纯净提取:使用 split("s320/") 安全剥离前缀,再通过 .filter(el => el) 清除空字符串;
  • 答案隔离:对每个题目(即第 i 个原始项),将其作为正确答案保留,其余项构成候选池;
  • 动态裁剪候选池:为凑齐 4 个选项(含 1 个正确答案),需从候选池中随机移除多余项,使剩余候选数恰好为 3;
  • 无冲突随机填充:用 while (options.includes(randomOption)) 循环重试,避免选项重复;
  • 答案注入与打乱:将正确答案插入随机位置的 4 元素数组中,再用 sort(() => Math.random() - 0.5) 实现真随机排序(更简洁可靠)。

✅ 推荐优化版代码(含注释)

function myFunction() {
  const input = document.getElementById("myList").value;
  const rawLines = input.split("\n").filter(line => line.trim() !== "");

  // 提取纯名称(如 "Apple.jpg"),移除 "s320/" 前缀
  const itemNames = rawLines
    .map(line => {
      const parts = line.split("s320/");
      return parts.length > 1 ? parts[1].trim() : line.trim();
    })
    .filter(name => name);

  let outputCode = "";

  for (let i = 0; i < itemNames.length; i++) {
    const answer = itemNames[i];
    // 构建候选选项池:排除当前答案的所有其他项
    const candidates = itemNames.filter((_, idx) => idx !== i);

    // 随机选取 3 个不重复的干扰项(若 candidates 不足 3 个,会自动截断,但建议输入 ≥ 4)
    const distractors = [];
    const tempPool = [...candidates]; // 浅拷贝防污染原数组
    while (distractors.length < 3 && tempPool.length > 0) {
      const randIdx = Math.floor(Math.random() * tempPool.length);
      distractors.push(tempPool.splice(randIdx, 1)[0]);
    }

    // 组合 4 个选项:答案 + 3 个干扰项 → 打乱顺序
    const allOptions = [...distractors, answer];
    for (let j = allOptions.length - 1; j > 0; j--) {
      const randIdx = Math.floor(Math.random() * (j + 1));
      [allOptions[j], allOptions[randIdx]] = [allOptions[randIdx], allOptions[j]]; // Fisher-Yates 洗牌
    }

    // 生成 Question 构造函数调用字符串
    const optionsStr = allOptions.map(opt => `"${opt}"`).join(", ");
    const questionText = `Choose ${answer} character from below!`;
    outputCode += `new Question("${questionText}", [${optionsStr}], "${answer}"),\n`;
  }

  document.getElementById("result").value = outputCode.trim();
}

⚠️ 关键注意事项

  • 输入要求:原始列表至少应包含 4 个有效项,否则干扰项不足,可能导致选项重复或缺失。若输入少于 4 项,建议增加校验并提示用户;
  • 性能考量:该算法时间复杂度为 O(n²)(因嵌套循环与 splice),但对于 ≤ 1000 条目的题库完全适用;超大规模场景可预计算洗牌索引以优化;
  • 随机性保障:避免使用 sort(() => Math.random() - 0.5) 替代 Fisher-Yates(存在偏差),本例已采用标准洗牌算法;
  • 字符安全:若 itemNames 含双引号、换行符等特殊字符,需额外转义(如 JSON.stringify() 替代手动拼接);
  • 可扩展性:如需支持 5 选项、多选题或图像 URL 直接嵌入,只需调整 allOptions 长度及 Question 构造参数即可。

此方案彻底摆脱了脆弱的字符串替换逻辑,以清晰的数据流和不可变操作思维实现高可靠性题库生成,兼顾教学实用性与工程健壮性。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

435

2023.08.07

json是什么
json是什么

JSON是一种轻量级的数据交换格式,具有简洁、易读、跨平台和语言的特点,JSON数据是通过键值对的方式进行组织,其中键是字符串,值可以是字符串、数值、布尔值、数组、对象或者null,在Web开发、数据交换和配置文件等方面得到广泛应用。本专题为大家提供json相关的文章、下载、课程内容,供大家免费下载体验。

543

2023.08.23

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

317

2023.10.13

go语言处理json数据方法
go语言处理json数据方法

本专题整合了go语言中处理json数据方法,阅读专题下面的文章了解更多详细内容。

81

2025.09.10

sort排序函数用法
sort排序函数用法

sort排序函数的用法:1、对列表进行排序,默认情况下,sort函数按升序排序,因此最终输出的结果是按从小到大的顺序排列的;2、对元组进行排序,默认情况下,sort函数按元素的大小进行排序,因此最终输出的结果是按从小到大的顺序排列的;3、对字典进行排序,由于字典是无序的,因此排序后的结果仍然是原来的字典,使用一个lambda表达式作为key参数的值,用于指定排序的依据。

399

2023.09.04

while的用法
while的用法

while的用法是“while 条件: 代码块”,条件是一个表达式,当条件为真时,执行代码块,然后再次判断条件是否为真,如果为真则继续执行代码块,直到条件为假为止。本专题为大家提供while相关的文章、下载、课程内容,供大家免费下载体验。

100

2023.09.25

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

465

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

213

2023.09.04

包子漫画网页版入口与全集阅读指南_正版免费漫画快速访问方法
包子漫画网页版入口与全集阅读指南_正版免费漫画快速访问方法

本专题汇总了包子漫画官网和网页版入口,提供最新章节抢先看方法、正版免费阅读指南,以及稳定访问方式,帮助用户快速直达包子漫画页面,无广告畅享全集漫画内容。

47

2026.02.10

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 4.9万人学习

TypeScript 教程
TypeScript 教程

共19课时 | 2.8万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 3.3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号