讲师中心 微信公众号
AI工具推荐 视频效率加速

使用Set实现JavaScript不重复随机数生成

阿墨同学_8838

阿墨同学_8838

发布时间:2025-11-15 12:41:02

|

629人浏览过

|

来源于php中文网

原创

使用Set实现JavaScript不重复随机数生成

本文将探讨在javascript中生成指定数量不重复随机数的方法。针对传统随机数生成可能出现重复的问题,我们将介绍如何利用javascript的set数据结构高效地确保生成数字的唯一性,并提供详细的代码示例及实现解析,帮助开发者构建可靠的随机数生成器。

在许多应用场景中,我们需要生成一系列随机数,并且要求这些随机数是唯一的,例如抽奖号码、验证码或游戏中的随机事件选择。然而,直接使用 Math.random() 结合 Math.floor() 生成随机数时,在多次调用后很有可能产生重复的数字,尤其是在生成数量相对较多的随机数时。

传统随机数生成的问题

考虑以下一个简单的随机数生成函数:

function sorteio() {
  const numeroAleatorio = (min, max) => {
    // 原始代码中此处为 Math.floor(Math.random() * 59 + 1),
    // 这将生成1到59的随机数。
    // 如果目标是1到60,则应为 Math.floor(Math.random() * (max - min + 1)) + min
    return Math.floor(Math.random() * 59 + 1); 
  };

  const gerarNumerosEntre1a60 = n => {
    const resultado = [];
    for (let i = 0; i < n; ++i) {
      resultado.push(numeroAleatorio(1, 60)); // 这里的(1, 60)参数并未被numeroAleatorio函数实际使用
    }
    return resultado;
  }

  document.getElementById("resultado").innerHTML = gerarNumerosEntre1a60(6);
}

上述代码尝试生成6个1到59之间的随机数。问题在于,numeroAleatorio 函数每次调用都是独立的,它不关心之前生成过哪些数字。因此,在循环中多次调用时,很有可能出现相同的数字被多次添加到 resultado 数组中的情况。为了确保生成的数字是唯一的,我们需要一种机制来跟踪已经生成的数字。

使用 Set 解决唯一性问题

JavaScript 中的 Set 对象是一种非常有用的数据结构,它允许你存储任何类型的唯一值。Set 的关键特性是,当你尝试向它添加一个已经存在的值时,Set 不会执行任何操作,即它只保留每个值的单个实例。这使得 Set 成为解决随机数唯一性问题的理想选择。

立即学习“Java免费学习笔记(深入)”;

我们可以利用 Set 的这一特性来构建一个高效的不重复随机数生成器:持续生成随机数并将其添加到 Set 中,直到 Set 的大小达到我们所需的数量。

实现不重复随机数生成器

以下是使用 Set 实现不重复随机数生成功能的完整代码:

Doc To HTML
Doc To HTML

使用 MinerU 文档处理引擎将 Word 文档(.doc、.docx)转换为保留结构和格式的干净 HTML。

下载
function sorteio() {
  /**
   * 生成指定范围内指定数量的不重复随机数
   * @param {number} min - 随机数的最小值(包含)
   * @param {number} max - 随机数的最大值(包含)
   * @param {number} count - 需要生成的随机数数量
   * @returns {Array<number>} 包含不重复随机数的数组
   */
  const getRandom = (min, max, count) => {
    // 校验参数:确保count不大于可能值的总数
    if (count > (max - min + 1)) {
      console.warn("请求的随机数数量超过了可能值的总数,将返回所有可能值。");
      count = max - min + 1; // 调整count为最大可能值
    }
    if (count <= 0) {
        return [];
    }

    const result = new Set(); // 使用Set来存储唯一的随机数
    while (result.size < count) {
      // 生成一个介于min和max之间的随机整数(包含min和max)
      const randomNumber = Math.floor(Math.random() * (max - min + 1)) + min;
      result.add(randomNumber); // 将随机数添加到Set中。如果已存在,Set不会重复添加
    }
    return [...result]; // 将Set转换为数组并返回
  };

  /**
   * 生成1到60之间指定数量的不重复随机数
   * @param {number} n - 需要生成的随机数数量
   * @returns {Array<number>} 包含不重复随机数的数组
   */
  const gerarNumerosEntre1a60 = n => {
    // 调用getRandom函数,指定范围为1到60
    const resultado = getRandom(1, 60, n);
    return resultado;
  };

  // 将生成的结果显示在页面上
  document.getElementById("resultado").innerHTML = gerarNumerosEntre1a60(6).join(', ');
}

HTML 结构:

<button onclick="sorteio()">Sortear numeros!</button>
<h1 id="resultado"></h1>

点击按钮后,sorteio 函数将被调用,并在 h1 标签中显示6个1到60之间不重复的随机数。

代码解析

  1. getRandom(min, max, count) 函数:

    • 参数校验: 在函数开头添加了简单的参数校验,确保 count 不会超过 min 到 max 之间所有可能数字的总数。如果 count 过大,会发出警告并调整 count 为最大可能值。
    • const result = new Set();: 创建一个空的 Set 对象,用于存储最终的不重复随机数。
    • while (result.size < count): 这是一个核心循环。它会一直执行,直到 Set 中存储的元素数量达到 count 所需的值。
    • *`const randomNumber = Math.floor(Math.random() (max - min + 1)) + min;:** 这是生成指定范围内(包含min和max`)随机整数的标准公式。
      • Math.random() 生成一个 [0, 1) 范围内的浮点数。
      • *(max - min + 1) 将范围扩大到 [0, max - min + 1)。
      • Math.floor() 向下取整,得到 [0, max - min] 范围内的整数。
      • + min 将整个范围平移到 [min, max]。
    • result.add(randomNumber);: 将生成的随机数添加到 Set 中。Set 会自动处理重复项,如果 randomNumber 已经存在于 result 中,add 方法将不会有任何效果,Set 的大小也不会改变。
    • return [...result];: 当 while 循环结束时,result Set 中包含了 count 个唯一的随机数。使用扩展运算符 (...) 可以方便地将 Set 转换为一个数组并返回。
  2. gerarNumerosEntre1a60(n) 函数:

    • 这是一个封装函数,专门用于生成1到60之间的随机数。它简单地调用 getRandom 函数,并传入固定的 min (1) 和 max (60) 值。
  3. 页面显示:

    • document.getElementById("resultado").innerHTML = gerarNumerosEntre1a60(6).join(', ');:获取 ID 为 "resultado" 的元素,并将其 innerHTML 设置为生成的6个随机数,使用逗号和空格连接成字符串显示。

注意事项与性能考量

  • 范围与数量的平衡: 尽管 Set 方法非常有效,但在极端情况下仍需注意。如果 count(需要生成的数量)非常接近 max - min + 1(可能值的总数),while 循环可能需要更多次迭代才能找到所有剩余的唯一数字。在最坏的情况下,如果 count 等于 max - min + 1,并且随机数生成器总是先生成重复的数字,性能会下降。
  • 极端情况的替代方案:
    • 小范围、大数量: 如果随机数的范围很小,但你需要几乎所有可能的数字(例如,从1到100中取90个不重复的数字),一个更高效的方法是创建一个包含所有可能数字的数组,然后对其进行 Fisher-Yates 洗牌算法,最后取出前 count 个元素。
    • 大范围、小数量: 对于大范围(例如,1到1,000,000)但只需要少量(例如,10个)不重复随机数的情况,Set 方法通常是最佳选择,因为它避免了创建和洗牌一个巨大的数组。

总结

通过巧妙地利用 JavaScript 的 Set 数据结构,我们可以轻松且高效地解决在生成随机数时遇到的重复问题。Set 的唯一性保证机制使得代码逻辑清晰、易于理解和维护。在实际开发中,根据随机数的范围和所需数量,选择最合适的生成策略,可以进一步优化性能。上述 Set 的实现提供了一个健壮且广泛适用的解决方案,适用于大多数不重复随机数生成的需求。

热门AI工具

更多
墨刀AI
墨刀AI Hot

一款AI图像与设计工具,主要用于产品经理的专属智能体,适合需要提升相关任务效率的用户。

Atoms
Atoms Hot

Atoms是一款AI智能体工具,第一支自动构建真实业务的 AI 团队。

PixPix
PixPix Hot

PixPix是一款面向电商视觉生产的AI商品图生成工具。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

Loomy
Loomy Hot

一款AI工具,主要用于科大讯飞发布的桌面级 AI 助理,比 OpenClaw 更易用、更安全!,适合需要提升相关任务效率的用户。

火山引擎

火山引擎是一款面向企业的云计算与AI服务平台。

二狗PPT
二狗PPT Hot

一款AI演示文稿工具,主要用于专为中式职场打造的AI PPT生成工具,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

相关专题

更多
java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

5824

2023.10.24

Go语言中的运算符有哪些
Go语言中的运算符有哪些

Go语言中的运算符有:1、加法运算符;2、减法运算符;3、乘法运算符;4、除法运算符;5、取余运算符;6、比较运算符;7、位运算符;8、按位与运算符;9、按位或运算符;10、按位异或运算符等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2464

2024.02.23

php三元运算符用法
php三元运算符用法

本专题整合了php三元运算符相关教程,阅读专题下面的文章了解更多详细内容。

1632

2025.10.17

counta和count的区别
counta和count的区别

Count函数用于计算指定范围内数字的个数,而CountA函数用于计算指定范围内非空单元格的个数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2528

2023.11.20

while的用法
while的用法

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

334

2023.09.25

c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

1978

2023.09.20

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

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

1578

2023.08.03

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

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

2324

2023.09.04

PixTV AI视频生成与无限画布创作
PixTV AI视频生成与无限画布创作

PixTV专题整理AI视频与视觉内容创作相关功能使用教程,涵盖AI生图、视频生成、无限画布、多模型创作、素材管理、声音音乐及视频剪辑等功能,帮助用户快速掌握PixTV从创意到成片的完整制作方法。

0

2026.09.29

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
WebStorm 官方调试文档
WebStorm 官方调试文档

共0课时 | 0人学习

React 教程
React 教程

共58课时 | 12万人学习

TypeScript 教程
TypeScript 教程

共19课时 | 6.5万人学习

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

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn