介绍
在前端开发中,洗牌(Shuffle)是一项基本操作,通常用于随机排序数组中的元素。JavaScript 中的数组有一个 sort() 方法,可以对数组进行排序,但是该方法存在着一定的问题,不能直接用于洗牌。本文将讨论如何使用 JavaScript 数组正确地洗牌。
sort() 方法的问题
sort() 方法是 JavaScript 数组原型中的一个方法,用于对数组进行排序。sort() 方法默认按照字符串 Unicode 码点进行升序排序,如果需要进行其他类型的排序,则需要传入一个比较函数作为参数。
const numbers = [1, 3, 2, 5, 4]; numbers.sort(); // [1, 2, 3, 4, 5] const words = ["apple", "banana", "cherry"]; words.sort(); // ["apple", "banana", "cherry"]
然而,由于 sort() 方法是在原数组上进行修改,因此不能直接用于洗牌。
const arr = [1, 2, 3, 4, 5]; arr.sort(); console.log(arr); // [1, 2, 3, 4, 5]
上述代码中,sort() 方法对 arr 数组进行了排序,但它并没有改变数组元素的位置,因此结果仍是原始数组。
正确地洗牌数组
要正确地洗牌数组,我们可以使用 Fisher–Yates shuffle 算法,该算法通过随机交换数组元素的位置来实现洗牌。下面是算法的具体步骤:
- 从数组的最后一位开始往前遍历,直到第一位(含)。假设当前遍历到的位置为 i。
- 在 0 到 i 之间(含)随机取一个整数 j。
- 交换数组中 i 和 j 位置上的元素。
function shuffle(arr) { for (let i = arr.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [arr[i], arr[j]] = [arr[j], arr[i]]; } }
在上述代码中,我们使用 for 循环从数组的最后一位开始往前遍历,然后在 0 到 i 之间随机选取一个整数 j,最后交换数组中 i 和 j 位置上的元素。这个过程会持续进行 n - 1 次,其中 n 是数组的长度,因此可以保证数组被正确地洗牌。
示例代码
下面是一个完整的洗牌示例:
-- -------------------- ---- ------- ----- --- - --- -- -- -- --- -------- ------------ - --- ---- - - ---------- - -- - - -- ---- - ----- - - ------------------------ - -- - ---- -------- ------- - -------- -------- - - ------------- ----------------- -- --- -- -- -- --
在上述代码中,我们首先定义了一个数组 arr,然后调用 shuffle() 方法对其进行洗牌,并输出结果。
总结
JavaScript 数组的 sort() 方法不能直接用于洗牌,需要使用 Fisher–Yates shuffle 算法来实现。该算法通过随机交换数组元素的位置来实现洗牌,可以保证每个元素出现在每个位置的概率相等。在实际开发中,正确地洗牌数组是一项基本技能,可以应用于各种场景,例如生成随机列表、打乱问题顺序等。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/10320