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

JavaScript随机不重复题目抽取求助:randomNumbers函数故障排查

嘿,我来帮你搞定这个随机抽题的问题!你卡了4小时肯定挺闹心的,咱们一步步拆解问题,然后给你一个靠谱的解决方案。

你的问题回顾

我正在开发一个程序,需从14道题目中随机抽取10道不重复的题目,但已卡壳4小时。问题出在randomNumbers()函数:该函数生成标记题目的随机数,检查numberArray中是否已存在该数,若不存在则推入数组。我认为问题源于VERSION 1中的for循环if/else条件逻辑,同时想确认while(true)是否为正确处理方式?VERSION 2为最初尝试方案(含大量console.log用于排查bug)。


问题根源

首先明确:while(true)本身是可行的(属于「生成-检查-直到符合条件」的常规写法),你的问题完全出在检查随机数重复的逻辑错误上:

  • VERSION 1里的for循环逻辑混乱:当数组长度大于1时,循环只检查到arrLength-1,而且只要遇到第一个不相等的元素就直接pushbreak,完全没检查后续元素是否和当前随机数重复。比如数组里已经有[2,5],生成随机数5,循环i=0时2≠5,就直接把5push进去,导致重复。
  • VERSION 2里的continue只是跳过当前循环迭代,但循环结束后没有重新生成随机数的逻辑,同样会导致重复的数被误加入数组。

修正后的完整方案

我们可以大幅简化randomNumbers()的逻辑,不用分数组长度的情况,直接用Array.indexOf()来检查随机数是否已存在,代码更清晰可靠:

完整HTML代码

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8"/>
<title>Testimiskeskkond</title>
<script src="scripts/jquery-2.1.4.min.js"></script>
<script src="scripts/js.js"></script>
</head>
<body>
<button onclick="startQuiz()">Alusta testimist</button>
<div id="question1"></div>
<div id="questions"></div>
</body>

修正后的JavaScript代码

var amountOfQuestions = 10; // 改为10,符合抽取10道题的需求
var questionCounter = 0;
var numberArray = []; // 用[]创建数组更简洁直观
var questions = [
    'Mitu kassi elab P2rnus?',
    'Mis on kassi nimi?',
    'Mida kass teeb?',
    'Millal kass syndis?',
    'Mitu hammast kassil on?',
    'Mitu kyynt on kassil?',
    'Mitu k6rva on kassil?',
    'Mis v2rvi on kass?',
    'Tooli v2rvus?',
    'Laua suurus?',
    'Lemmik jook?',
    'Lemmik s88k?',
    'Raamatupoe nimi?',
    'Viinapoe nimi?'
];

function startQuiz() {
    var setQuestions = "";
    // 每次点击按钮重置计数器和数组,避免重复抽题
    questionCounter = 0;
    numberArray = [];
    
    while (questionCounter < amountOfQuestions) {
        var random = randomNumbers();
        setQuestions += questions[random] + "<br>";
        questionCounter += 1;
    }
    $('#questions').html(setQuestions);
}

function randomNumbers() {
    while (true) {
        var randomNr = Math.floor(Math.random() * 14);
        // 检查随机数是否未被选中过
        if (numberArray.indexOf(randomNr) === -1) {
            numberArray.push(randomNr);
            return randomNr; // 符合条件就返回,跳出循环
        }
        // 如果已存在,自动继续循环生成新的随机数
    }
}

额外优化说明

  1. 修正了amountOfQuestions的值:你需要抽取10道题,原来的11是错误的
  2. 点击按钮时重置计数器和数组:避免多次点击按钮时,重复使用之前的抽题记录
  3. 简化了startQuiz()的逻辑:不用分if/else处理最后一题,多余的<br>对显示影响极小,若想完美处理可以最后用setQuestions.slice(0, -4)去掉末尾的<br>
  4. []替代new Array():这是JS里创建数组更常用的简洁写法

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

火山引擎 最新活动