You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript借助chance.js随机抽题时 如何避免生成重复的问题数组

随机抽题去重的落地实现方案

问题根因

你现在的逻辑是直接生成随机索引取题,没有对已抽取的条目做去重校验——哪怕题库有2000+道题,多次随机生成索引时仍有小概率命中之前已经抽过的下标,最终出现重复题目。下面两种方案都适配你现有业务(含后续支持1-100自定义抽题量的需求),可以根据改造成本选择:

方案1:Set集合校验索引(改动最小)

完全复用你现有的循环结构,额外加一个存储已抽题目标识的Set结构做快速去重:因为Set的查找时间复杂度是O(1),不会带来额外性能开销。
核心逻辑就是每次生成随机索引后,先看这个索引有没有被用过,如果重复就重新生成,直到拿到没被使用的索引,再推入待作答数组。

this.askQuestions = [];        
this.questions = JSON.parse(this.questionsData);
// 存储已经抽过的题目原始下标,用于快速去重
const usedIndexes = new Set();
// 后续替换成用户自定义抽题量,调试阶段固定为10即可
const needCount = 10;
// 兜底:抽题量不能超过题库总长度,避免出现无限循环
const validCount = Math.min(needCount, this.questions.length);

for(let i = 0; i < validCount; i++){
    let n;
    // 先生成随机索引,再校验是否被使用过
    do {
        n = chance.integer({min: 0, max: this.questions.length - 1});
    } while(usedIndexes.has(n));
    usedIndexes.add(n);

    this.askQuestions.push({
        questionIndex: n,
        question: this.questions[n].question,
        choices: this.questions[n].possibleAnswers
    });
}

这个方案的优势是几乎不动原有代码,2000+题库抽10-100题时,索引碰撞的概率极低,极少触发重试,性能完全能覆盖业务场景。

方案2:Fisher-Yates洗牌算法(长期最优)

如果后续抽题量可能持续提升,直接用经典的洗牌算法从根源避免重复:先把题库数组随机打乱顺序,再直接截取需要的题目数量,全程没有索引碰撞、重试的过程,哪怕抽取量接近题库总长度,性能也不会衰减。

this.askQuestions = [];        
this.questions = JSON.parse(this.questionsData);
const needCount = 10;
const validCount = Math.min(needCount, this.questions.length);

// 拷贝一份题库数组做操作,避免修改原始题库数据
const questionPool = [...this.questions];
// 执行Fisher-Yates无重复随机打乱
for (let i = questionPool.length - 1; i > 0; i--) {
    // 借助chance生成随机交换位置
    const randomIdx = chance.integer({min: 0, max: i});
    [questionPool[i], questionPool[randomIdx]] = [questionPool[randomIdx], questionPool[i]];
}
// 直接截取前N条就是完全随机、无重复的题目
this.askQuestions = questionPool.slice(0, validCount).map((item, index) => ({
    questionIndex: index,
    question: item.question,
    choices: item.possibleAnswers
}))

注意:不要用题目文本内容做去重判断,实际业务题库可能存在重复录入的同题干题目,用题库里的原始下标做去重标识,才能保证每一条抽取的条目都对应库内唯一的记录。

后续支持自定义抽题量时,只需要把固定的needCount替换为用户传入的1-100区间值,保留和题库总长度的兜底判断即可,两种方案都可以直接适配。


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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.23 23:45:11