如何检测randomNum已选文本行并避免重复选取?
避免重复选取文本行的实现方案
针对你的四选项答题系统需求,要解决随机选行不重复的问题,核心是跟踪已选取的行索引,以下两种实用方案供你选择:
方案一:用Set记录已选索引(适合需要保留原行数组的场景)
这种方法通过Set存储已经选过的行索引,每次生成随机数后检查是否已存在,直到找到未被选中的索引:
fetch('./Test.txt', { credentials: 'same-origin', mode: 'same-origin', }) .then(response => response.text()) .then(data => { // 拆分文本为行数组,过滤空行避免无效数据 const lines = data.split('\n').filter(line => line.trim() !== ''); const totalLines = lines.length; // 存储已选过的行索引,Set的查找效率远高于数组 const selectedIndexes = new Set(); // 获取不重复随机行的函数 function getUniqueRandomLine() { // 所有行都选过的情况:重置已选集合或提示用户 if (selectedIndexes.size >= totalLines) { selectedIndexes.clear(); console.log('所有题目已完成,将重新抽取'); } let randomNum; // 循环生成随机数,直到找到未被选中的索引 do { randomNum = Math.floor(Math.random() * totalLines); } while (selectedIndexes.has(randomNum)); // 标记该索引为已选 selectedIndexes.add(randomNum); // 返回对应的题目行数据 return lines[randomNum]; } // 调用示例:获取一道新题并渲染 const newQuestion = getUniqueRandomLine(); console.log(newQuestion); // 这里添加你的HTML渲染逻辑,比如把内容插入到答题区域 });
方案二:抽取后移除行(更高效,适合不需要保留原数组的场景)
这种方法直接维护一个“剩余可选行”数组,每次抽取后把该行从数组中移除,后续只在剩余行里随机选取,无需循环检查:
fetch('./Test.txt', { credentials: 'same-origin', mode: 'same-origin', }) .then(response => response.text()) .then(data => { // 初始化剩余可选行数组,过滤空行 let availableLines = data.split('\n').filter(line => line.trim() !== ''); // 获取不重复随机行的函数 function getUniqueRandomLine() { // 所有行都选完的情况:重置可选数组 if (availableLines.length === 0) { availableLines = data.split('\n').filter(line => line.trim() !== ''); console.log('所有题目已完成,将重新开始'); } // 在剩余行中生成随机索引 const randomNum = Math.floor(Math.random() * availableLines.length); // 从数组中移除并返回选中的行 const selectedLine = availableLines.splice(randomNum, 1)[0]; return selectedLine; } // 调用示例 const newQuestion = getUniqueRandomLine(); console.log(newQuestion); // 执行你的渲染逻辑 });
额外优化点
- 原代码中变量未用
const/let声明,会变成全局变量,建议始终用const(值不变时)或let(值需要修改时)声明变量,避免全局污染。 - 拆分文本时建议过滤空行,避免读取到Test.txt末尾的空白无效行。
内容的提问来源于stack exchange,提问作者ftk789
相关产品推荐
相关产品推荐

