JavaScript 产生不重复的随机数三种实现思路


在JavaScript中生成不重复的随机数,我们可以考虑几种不同的实现思路。以下是三种常见的实现方式:

### 1. 使用Set数据结构

`Set` 是ES6中新增的一种数据结构,它类似于数组,但是成员的值都是唯一的,没有重复的值。


function generateUniqueRandomNumbers(min, max, count) {
    const set = new Set();
    while (set.size < count) {
        set.add(Math.floor(Math.random() * (max - min + 1)) + min);
    }
    return [...set];
}

// 示例
const uniqueNumbers = generateUniqueRandomNumbers(1, 10, 5);
console.log(uniqueNumbers);

### 2. 数组排序加随机交换

首先生成一个包含指定范围内所有数字的数组,然后对这个数组进行排序。接着,通过随机交换数组中的元素来打乱数组的顺序,最后根据需要取出前N个元素作为不重复的随机数。


function shuffleArray(array) {
    for (let i = array.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        [array[i], array[j]] = [array[j], array[i]];
    }
}

function generateUniqueRandomNumbers(min, max, count) {
    const numbers = [];
    for (let i = min; i <= max; i++) {
        numbers.push(i);
    }
    shuffleArray(numbers);
    return numbers.slice(0, count);
}

// 示例
const uniqueNumbers = generateUniqueRandomNumbers(1, 10, 5);
console.log(uniqueNumbers);

### 3. 使用Fisher-Yates洗牌算法

Fisher-Yates洗牌算法是一种在数组中随机打乱元素顺序的有效方法,它也可以用于生成不重复的随机数。


function fisherYatesShuffle(array) {
    for (let i = array.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        [array[i], array[j]] = [array[j], array[i]];
    }
    return array;
}

function generateUniqueRandomNumbers(min, max, count) {
    const numbers = [];
    for (let i = min; i <= max; i++) {
        numbers.push(i);
    }
    return fisherYatesShuffle(numbers).slice(0, count);
}

// 示例
const uniqueNumbers = generateUniqueRandomNumbers(1, 10, 5);
console.log(uniqueNumbers);

以上三种方法各有特点,第一种方法适用于需要生成较小范围内的随机数的场景,第二种和第三种方法适用于需要生成较大范围内随机数的场景,且它们都可以确保生成的随机数是唯一的。