如何在 JavaScript 中对一个数组进行随机化或洗牌
在本篇文章中,我们将学习如何在 JavaScript 中对一个数组进行洗牌或随机化处理;在 JavaScript 中洗牌数组的方法有很多,不管是通过实现洗牌算法还是使用一些库中已有的洗牌函数。
洗牌数组就是将其元素随机排列,所以主要看你如何对数组进行一定程度的重新排序或分类。
让我们继续前进,发现随机化或洗牌一个数组的不同方法。
让我们先实现一个简单的数组洗牌算法,使用 array.sort()
对数组进行排序,但使用 Math.random()-0.5
等式产生的一些随机性,-0.5
确保每次调用算法时,随机值可以是正值或负值。
让我们借助 JavaScript 引擎的力量实现这个简单的算法,并使用 Console.log()
将洗牌后的 Array 打印到控制台。
function shuffleArray(inputArray){
inputArray.sort(()=> Math.random() - 0.5);
}
var demoArray = [1, 3, 5];
shuffleArray(demoArray);
console.log(demoArray);
输出:
[1, 5, 3]
可以计算出该数组的排列概率,以检查我们实现的算法有多优秀、多随机。
我们来看看如何衡量它的随机性。
这个简单的测量算法可以像下面这样实现。
function shuffleArray(inputArray){
inputArray.sort(()=> Math.random() - 0.5);
}
//counts of the appearances for all possible permutations
var countDic = {
'153': 0,
'135': 0,
'315': 0,
'351': 0,
'531': 0,
'513': 0,
};
//Creating the loop
for( var i = 0; i<1000000; i++){
var arr = [ 1 , 5 , 3];
shuffleArray(arr);
countDic[arr.join('')]++;
}
//Print the counts of all possible permutations
for(var key in countDic){
console.log(`${key}: ${countDic[key]}`);
}
输出:
135: 62256
153: 375832
315: 62976
351: 311865
513: 124518
531: 62553
从上面的输出中,我们可以清楚地看到偏差,因为 135
、315
、531
出现的次数比其他的少得多,所以彼此之间的计数相似。
这种基于 JavaScript 引擎的简单算法在过去的部分中是不可靠的,但是一个叫做 Fisher-Yates
的伟大算法就其效率和可靠性而言是更好的。
Fisher-Yates
算法背后的思想是以相反的顺序走到数组,并将每个元素与前面的随机元素交换。Fisher-Yates
是一个简单但非常有效和快速的算法。
让我们来实现 Fisher-Yates
算法。
function fisherYatesShuffle(arr){
for(var i =arr.length-1 ; i>0 ;i--){
var j = Math.floor( Math.random() * (i + 1) ); //random index
[arr[i],arr[j]]=[arr[j],arr[i]]; // swap
}
}
var tmpArray = [1, 3, 5];
fisherYatesShuffle(tmpArray);
console.log(tmpArray);
我们来一步步解释一下吧
输出:
(3) [3, 1, 5]
现在让我们用之前的方法测试 Fisher -Yates
。
//counts of the appearances for all possible permutations
var countDic = {
'153': 0,
'135': 0,
'315': 0,
'351': 0,
'531': 0,
'513': 0,
};
//Creating the loop
for( var i = 0; i<1000000; i++){
var arr = [ 1 , 5 , 3];
fisherYatesShuffle(arr);
countDic[arr.join('')]++;
}
//Print the counts of all possible permutations
for(var key in countDic){
console.log(`${key}: ${countDic[key]}`);
}
输出:
135: 166734
153: 166578
315: 166908
351: 166832
513: 166535
531: 166413
从上面的输出,你可以看到 Fisher-Yates
算法和我们之前实现的简单算法之间的巨大差异,以及 Fisher-Yates
算法的可靠性。
著名的 Underscore.js
库也提供了一个 shuffle 函数,可以直接随机化一个数组,而不需要你写任何算法的实现。
下面我们来看一下 _.shuffle()
方法的使用实例。
首先,我们需要在 HTML 模板里面使用 Cloudflare CDN
导入这个库。
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>
然后我们使用 _.shuffle()
方法,如。
var tmpUnderscoreArray = [1, 3, 5];
resultArray = _.shuffle(tmpUnderscoreArray);
console.log(resultArray);
输出:
(3) [1, 5, 3]
相关文章
在 Angular 中上传文件
发布时间:2023/04/14 浏览次数:71 分类:Angular
-
本教程演示了如何在 Angular 中上传任何文件。我们还将介绍如何在文件上传时显示进度条,并在上传完成时显示文件上传完成消息。
Angular 中所有 Mat 图标的列表
发布时间:2023/04/14 浏览次数:91 分类:Angular
-
本教程演示了在哪里可以找到 Angular 中所有 Mat 图标的列表以及如何使用它们。
Angular 2 中的复选框双向数据绑定
发布时间:2023/04/14 浏览次数:139 分类:Angular
-
本教程演示了如何一键标记两个复选框。这篇有 Angular 的文章将着眼于执行复选框双向数据绑定的不同方法。
在 AngularJS 中重新加载页面
发布时间:2023/04/14 浏览次数:142 分类:Angular
-
我们可以借助 windows.location.reload 和 reload 方法在 AngularJS 中重新加载页面。
在 AngularJs 中设置 Select From Typescript 的默认选项值
发布时间:2023/04/14 浏览次数:78 分类:Angular
-
本教程提供了在 AngularJs 中从 TypeScript 中设置 HTML 标记选择的默认选项的解释性解决方案。
在 AngularJS 中启用 HTML5 模式
发布时间:2023/04/14 浏览次数:150 分类:Angular
-
本文讨论如何在 AngularJS 应用程序上启用带有深度链接的 HTML5 模式。
在 AngularJs 中加载 spinner
发布时间:2023/04/14 浏览次数:107 分类:Angular
-
我们将介绍如何在请求加载时添加加载 spinner,并在 AngularJs 中加载数据时停止加载器。
在 Angular 中显示和隐藏
发布时间:2023/04/14 浏览次数:78 分类:Angular
-
本教程演示了 Angular 中的显示和隐藏。在开发商业应用程序时,我们需要根据用户角色或条件隐藏一些数据。我们必须根据该应用程序中的条件显示相同的数据。
在 Angular 中下载文件
发布时间:2023/04/14 浏览次数:104 分类:Angular
-
本教程演示了如何在 angular 中下载文件。我们将介绍如何通过单击按钮在 Angular 中下载文件并显示一个示例。