如何随机化(洗牌)JavaScript数组?


在本教程中,我们将学习随机化或洗牌 JavaScript 数组的方法。

我们可以通过使用某些库或算法中现有的洗牌函数来实现这一点。

让我们继续讨论。

使用 Fisher-Yates 算法和解构赋值

在这里,算法从最后一个索引迭代到第一个索引。在每个循环中,它交换数组值并创建有限序列的随机排列。

我们可以按照以下语法使用此算法。

语法

for (var i=arr.length – 1;i>0;i--) {
   var j = Math.floor(Math.random() * (i + 1));
   [arr[i], arr[j]] = [arr[j], arr[i]];
}

这里,解构赋值语法用于交换循环内两个变量的值。

算法

  • 步骤 1 - 列出从 1 到 N 的数字。

  • 步骤 2 - 在 1 到剩余数字之间选择一个随机值 x。

  • 步骤 3 - 将从末尾开始的第 x 个值放入新列表中,并从实际列表中删除第 x 个值。

  • 步骤 4 - 重复步骤 2,直到列表中的所有值都被删除。

  • 步骤 5 - 步骤 3 中的新列表是实际列表的随机排列。

示例

在此代码中,我们在一行代码中交换了两个变量的值。根据 Fisher-Yates 算法,我们的程序会对输入数组进行洗牌并显示输出。

<html> <body> <p id = "data"></p> <p id="result"></p> <script> function fisherYatesRandomize(arr) { for (var i = arr.length - 1; i > 0; i--) { var j = Math.floor(Math.random() * (i + 1)); [arr[i], arr[j]] = [arr[j], arr[i]]; } return arr; } var fshArray = [10, 20, 30, 40, 50, 60]; document.getElementById("data").innerHTML = "Original Array - " +fshArray document.getElementById("result").innerHTML = "Shuffled Array - " + fisherYatesRandomize(fshArray); </script> </body> </html>

使用 Drustenfield 洗牌

Drustenfield 算法是Fisher-Yates算法的优化版本。

该算法为每个数组索引选择一个随机值,并从下一个选择中排除此值。这与从一副牌中抽牌完全一样。此循环向后工作。因此,这里的效率是最优的。O(n) 是此算法的运行时间。

用户可以按照以下语法使用此算法。

语法

for (var i = arr.length - 1; i > 0; i--)
{
   var j = Math.floor(Math.random() * (i + 1));
   var temp = array[i];
   array[i] = array[j];
   array[j] = temp;
}

这里,交换是在循环内借助新变量完成的。

算法

  • 步骤 1 - 令数组长度为 len

  • 步骤 2 - 从索引 len-1 和 1 的值循环。递减循环控制 lc。

  • 步骤 3 - 从当前 lc 和 1 中选择一个随机值 n。

  • 步骤 4 - 交换索引 n 和 lc 的值。因此,随机值会向下一个迭代索引移动。

  • 步骤 5 - 继续步骤 2 和后续步骤,直到循环结束。

示例

在此示例中,我们将数组传递给循环。Math.random() 和常规交换在循环内从最后一个索引到第一个索引工作。循环执行后返回洗牌后的数组。

<html> <body> <h3> Shuffle a JavaScript array using <i>Drustenfield shuffle algorithm</i> </h3> <p id="data"></p> <p id="result"></p> <script> function doShuffle(array) { for (var i = array.length - 1; i > 0; i--) { var j = Math.floor(Math.random() * (i + 1)); var temp = array[i]; array[i] = array[j]; array[j] = temp; } return array; } var drsArr = [100, 200, 300, 400, 500, 600]; document.getElementById("data").innerHTML = "Original Array - " + drsArr document.getElementById("result").innerHTML = "Shuffled Array - " + doShuffle(drsArr); document.getElementById("result").innerHTML = "Shuffled Array - " + doShuffle(drsArr); </script> <p> Note: You may get different shuffled array each time when you run the program </body> </html>

使用 Array sort() 方法

在这里,我们将讨论sort()方法。Sort 依赖于 JavaScript 引擎。Math.random()值在每次执行时都可能是正数或负数。这将返回 0 到 0.999 之间的值。Math.random() – 0.5 返回 -0.5 到 0.499 之间的值。

当 value1 和 value2 的排序结果大于 0 时,value1 将放在 value2 之前。这是逻辑。

sort 方法会修改原始数组。如果您需要原始数组的副本,可以使用下面给出的扩展运算符语法。

语法

arr.sort(function(a, b)
{
   return Math.random() - 0.5;
});

//Arrow function syntax
arr.sort(() => Math.random() - 0.5);

//The spread operator syntax
[...arr].sort(() => Math.random() - 0.5);

通常,数组的两个值会被传递给 sort 函数,就像在第一个语法中一样。因为我们没有在函数内部使用它,所以我们可以消除参数。

示例

在此示例中,sort 方法使用 Math.random() – 0.5 逻辑以随机顺序对输入数组值进行排序。

<html> <body> <h3>Shuffle a JavaScript array using the <i>array sort()</i> method</h3> <p id="data"></p> <p id="result"></p> <script> let srtLst = [1, 2, 3, 4, 5, 6, 7]; document.getElementById("data").innerHTML = "Original Array - " + srtLst srtLst = srtLst.sort(() => Math.random() - 0.5); document.getElementById("result").innerHTML = "Shuffled array - " + srtLst; </script> <p>Note: You may get different shuffled array each time when you run the program</p> </body> </html>

使用 underscore.js/Lo-Dash 库

我们将了解如何在程序中实现此库方法。我们这里不需要任何算法。此库具有_.shuffle()方法。首先,我们将库导入到脚本标签中。

语法

_.shuffle(arr);

这里,输入数组被传递给此库的 shuffle 方法。

参数

  • arr - 输入数组

示例

在此程序中,我们添加了一个库文件。shuffle 方法处理我们的输入数组并显示洗牌后的数组。

<html> <head> <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script> </head> <body> <h3> Shuffle a JavaScript array using <i>Underscore js library</i> </h3> <p id="libShuffOp"></p> <script> var libArray = ["Green", "Blue", "White"]; libResArray = _.shuffle(libArray); document.getElementById("libShuffOp").innerHTML = "Shuffled array - " + libResArray; </script> </body> </html>

本教程帮助我们学习了两种算法方法、数组排序方法和一种 JavaScript 库方法来随机化 JavaScript 数组。

Drustenfield 算法方法高效、快速且可靠。数组排序方法不可靠,因为没有明确的模式。Underscore.js 库会增加负载,因此将其作为最终选项。

更新于: 2022-09-06

2K+ 次浏览

开启你的 职业生涯

通过完成课程获得认证

开始学习
广告