如何随机化(打乱)JavaScript数组?

javascriptweb developmentfront end technology

在本教程中,我们将学习随机化或打乱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>

使用数组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;
});

//箭头函数语法
arr.sort(() => Math.random() - 0.5);

//扩展运算符语法
[...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 库会增加负载,因此将其作为最终选项。


相关文章