JavaScript:生成指定数量不重复随机数并获取最小值的技巧

JavaScript:生成指定数量不重复随机数并获取最小值的技巧
最新回答
虐爆托儿所

2020-07-25 09:38:12

在JavaScript中生成指定数量不重复随机数并获取最小值,可通过以下专业方案实现:

核心解决方案
  1. 使用Set数据结构确保唯一性Set对象会自动过滤重复值,通过循环生成随机数并添加到Set中,直到Set大小达到所需数量。

  2. 结合Math.min()与展开运算符获取最小值将Set元素展开为Math.min()的参数,直接返回最小值。

完整代码实现/ * 生成指定数量的唯一随机整数,并返回最小值 * @param {number} count - 生成数量 * @param {number} min - 最小值(包含) * @param {number} max - 最大值(包含) * @returns {number | undefined} - 最小值,无效输入返回undefined */function getSmallestUniqueRandomNumbers(count, min, max) { // 参数校验 if (count <= 0) { console.warn("生成数量必须大于0"); return undefined; } if (count > (max - min + 1)) { console.error(`请求数量${count}超过范围${min}-${max}的总数${max - min + 1}`); return undefined; } // 生成唯一随机数 const uniqueNumbers = new Set(); while (uniqueNumbers.size < count) { const randomNumber = Math.floor(Math.random() * (max - min + 1)) + min; uniqueNumbers.add(randomNumber); } // 获取最小值 const smallest = Math.min(...Array.from(uniqueNumbers)); console.log(`生成的${count}个${min}-${max}随机数:`, [...uniqueNumbers]); console.log("最小值:", smallest); return smallest;}// 示例调用getSmallestUniqueRandomNumbers(3, 1, 100); // 生成3个1-100的随机数并返回最小值关键步骤解析
  1. 随机数生成公式Math.floor(Math.random() * (max - min + 1)) + min

    Math.random()生成[0,1)的浮点数。

    乘以(max - min + 1)后取整,得到[0, max-min]的整数。

    加上min后,范围变为[min, max]。

  2. Set去重机制

    循环调用uniqueNumbers.add(randomNumber),Set会自动忽略重复值。

    当Set大小等于count时停止循环。

  3. 最小值计算

    Array.from(uniqueNumbers)将Set转为数组。

    Math.min(...array)通过展开运算符获取最小值。

注意事项
  • 参数校验

    确保count > 0且count ≤ (max - min + 1),否则返回undefined并提示错误。

  • 性能优化

    当count接近(max - min + 1)时,循环可能多次重复生成已存在的数字。此时可改用Fisher-Yates洗牌算法

    生成包含min到max的数组。

    随机打乱数组顺序。

    取前count个元素。

  • 极端情况处理

    若min === max且count === 1,直接返回min。

替代方案(Fisher-Yates洗牌)

适用于需要生成大量唯一随机数且范围较小的场景:

function getSmallestUniqueRandomNumbersFisherYates(count, min, max) { if (count <= 0 || count > (max - min + 1)) return undefined; // 生成并打乱数组 const numbers = Array.from({ length: max - min + 1 }, (_, i) => i + min); for (let i = numbers.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [numbers[i], numbers[j]] = [numbers[j], numbers[i]]; } // 取前count个元素 const uniqueNumbers = numbers.slice(0, count); const smallest = Math.min(...uniqueNumbers); console.log("随机数:", uniqueNumbers, "最小值:", smallest); return smallest;}总结
  • Set方案:代码简洁,适合大多数场景。
  • Fisher-Yates方案:在count接近范围总数时效率更高。
  • 核心技巧:利用Set去重和展开运算符简化最小值计算,避免低效的两两比较。