Skip to content

实现一个 shuffle 函数

TIP

在 TypeScript 中,你可以实现一个 shuffle 函数来随机打乱数组中的元素。以下是一个使用 Fisher-Yates 算法的实现

ts
function shuffle<T>(array: T[]): T[] {
    // 创建一个数组的副本,避免修改原数组
    const shuffledArray = [...array];
    let currentIndex = shuffledArray.length;

    // 当还有未处理的元素时
    while (currentIndex !== 0) {
        // 随机选择一个未处理的元素
        const randomIndex = Math.floor(Math.random() * currentIndex);
        currentIndex--;

        // 交换当前元素和随机选择的元素
        [shuffledArray[currentIndex], shuffledArray[randomIndex]] = [
            shuffledArray[randomIndex],
            shuffledArray[currentIndex],
        ];
    }

    return shuffledArray;
}

// 示例用法
const originalArray = [1, 2, 3, 4, 5];
const shuffledArray = shuffle(originalArray);

console.log(shuffledArray); // 输出可能是 [3, 1, 5, 2, 4] 或其他随机顺序

解释:

  • Fisher-Yates 算法:该算法通过从数组的末尾开始,随机选择一个元素并与当前元素交换,逐步向前处理,直到所有元素都被处理过。这样可以确保每个元素都有相等的概率出现在任何位置。

  • Math.random():生成一个 [0, 1) 之间的随机数。

  • Math.floor():将随机数向下取整,得到一个整数索引。

注意事项:

  • 这个实现不会修改原始数组,而是返回一个新的打乱后的数组。如果你希望直接修改原数组,可以将 shuffledArray 直接赋值给 array。
  • 这个实现使用了 ES6 的解构赋值语法,如果你的 TypeScript 版本不支持,可以改为使用数组的 swap 方法。

直接修改原数组的版本:

ts
function shuffleInPlace<T>(array: T[]): T[] {
    let currentIndex = array.length;

    while (currentIndex !== 0) {
        const randomIndex = Math.floor(Math.random() * currentIndex);
        currentIndex--;
        [array[currentIndex], array[randomIndex]] = [array[randomIndex], array[currentIndex]];
    }

    return array;
}

// 示例用法
const array = [1, 2, 3, 4, 5];
shuffleInPlace(array);

console.log(array); // 输出可能是 [3, 1, 5, 2, 4] 或其他随机顺序

这个版本的 shuffleInPlace 函数会直接修改传入的数组。

如有转载或 CV 的请标注本站原文地址