如何避免Math.random()返回重复结果?解决JSON随机内容重复问题
解决随机台词重复问题(遍历完所有条目前不重复)
你的问题出在每次点击都直接从完整的台词数组里随机挑选,完全没排除已经选过的条目,所以重复是概率性必然事件。要实现「遍历完所有条目之前不重复」的效果,核心思路是维护一个剩余未选条目的数组,每次从这个剩余数组里随机选,选完就把该条目从剩余数组中移除;等剩余数组空了,再重新加载原数据,循环往复。
修改后的代码如下:
const kaneki = document.querySelector("#kaneki-button"); if (kaneki) { // 维护剩余未选的条目数组,放在事件监听外面避免每次重置 let remainingQuotes = []; kaneki.addEventListener("click", function () { // 如果剩余数组为空,先加载数据并初始化剩余数组 if (remainingQuotes.length === 0) { fetch("json/ghoul.json") .then((response) => response.json()) .then((data) => { // 浅拷贝原数组到剩余数组,避免修改原数据 remainingQuotes = [...data]; // 初始化后立即执行一次选台词逻辑 pickAndDisplayQuote(); }); } else { // 剩余数组有内容,直接选台词 pickAndDisplayQuote(); } }); // 抽选并展示台词的逻辑封装成函数,避免重复代码 function pickAndDisplayQuote() { // 从剩余数组里随机选一个索引 const randomIndex = Math.floor(Math.random() * remainingQuotes.length); // 取出选中的条目 const animeData = remainingQuotes[randomIndex]; // 从剩余数组中移除该条目,避免重复选中 remainingQuotes.splice(randomIndex, 1); // 更新页面内容 document.getElementById("quote").innerHTML = animeData.quote; document.getElementById("character").innerHTML = animeData.character; } }
关键逻辑说明:
- 把
remainingQuotes放在事件监听外部,确保每次点击都能复用同一个剩余数组,记录已选过的条目 - 用
[...data]浅拷贝原JSON数据,避免后续splice操作修改原数据 - 当剩余数组为空时,重新加载数据并填充剩余数组,实现循环遍历
- 把抽选和展示逻辑封装成函数,减少代码重复
内容的提问来源于stack exchange,提问作者preston17
相关产品推荐
相关产品推荐

