通过js随机函数Math.random实现乱序
乱序的意思想必没有不知道就是将数组打乱。听到乱序一般都会想到js的随机函数Math.random();
var values = [1, 2, 3, 4, 5]; values.sort(function() { return Math.random() - 0.5; }); console.log(values)
利用数组的sort方法,判断随机出来的0~1值与0.5的大小,实现排序。看似一个很不错的方案,代码逻辑也没毛病,一般情况下也确实能够做到乱序。,这是一个伪排序,是的还有(我也是今天才知道的,不求甚解的毛病啊~),为什么呢?先看看这个乱序的结果吧
var times = [0, 0, 0, 0, 0]; for (var i = 0; i < 100000; i++) { let arr = [1, 2, 3, 4, 5]; arr.sort(() => Math.random() - 0.5); times[arr[4] - 1]++; }; console.log(times)
测试的原理是将[1, 2, 3, 4, 5]乱序10万次,计算乱序后数组的一个元素是1,2,3,4,5的次数分别是多少。
运行几次得到的结果为
由这几次运行得到的结果可以看出2出现的的次数明显少于其他数字,不是随机吗?按理说概率应该是相差不多才对啊!
其实问题是在sort方法,各个浏览器对sort的实现方式不一样。
Chrome的sort
基于V8引擎,它的排序算进行了很多的优化,核心是小于等于10的数组用插入排序(稳定),大于10的采用了quickSort(不稳定)
FireFox的sort
基于SpiderMonkey引擎,采用了归并排序(稳定)
Safari的sort
基于Nitro(JavaScriptCore )引擎,如果没有自定义的排序规则传入,采用桶排序(不一定稳定, 桶排序的稳定性取决于桶内排序的稳定性, 其稳定性不确定。),传入自定义规则,采用归并排序(稳定)
Microsoft Edge/IE9+
基于Chakra引擎,采用快排(不稳定)
以下用chrome测试乱序各种结果的概率
var times = 100000; var res = {}; for(var i = 0; i < times; i++){ var arr = [1, 2, 3]; arr.sort(() => Match.random() - 0.5); var key = JSON.stringify(arr); res[key] ? res[key]++ : res[key] = 1; } // 为了方便展示,转换成百分比 for (var key in res) { res[key] = res[key] / times 100 + '%'; } console.log(res);
结果如下
几种结果出现的概率相差很大...所以说不是一个真正的乱序。
Fisher-Yates算法【也叫“洗牌算法”】为什么叫 Fisher–Yates 呢? 因为这个算法是由 Ronald Fisher 和 Frank Yates 提出的。代码如下
function shuffle(a) { var j, x, i; for (i = a.length; i; i--) { j = Math.floor(Math.random() i); x = a[i-1]; a[i - 1] = a[j]; a[j] = x; } return a; }
其原理就是遍历数组元素,然后将当前元素与以后随机位置的元素进行交换,这样乱序更加彻底。
如果用ES6的写法还能精简成
function shuffle(a) { for(let i = a.length; i; i--) { let j = Math.floor(Math.random() i); [a[i - 1], a[j]] = [a[j], a[i - 1]]; } return a; }
再用上面的demo测试一下
var times = 100000; var res = {}; for (var i = 0; i < times; i++) { var arr = shuffle([1, 2, 3]); var key = JSON.stringify(arr); res[key] ? res[key]++ : res[key] = 1; } // 为了方便展示,转换成百分比 for (var key in res) { res[key] = res[key] / times 100 + '%' } console.log(res)
得到结果如下
各种结果的概率都基本相同了,所以真正实现了乱序的效果!
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持狼蚁SEO。
编程语言
- 如何快速学会编程 如何快速学会ug编程
- 免费学编程的app 推荐12个免费学编程的好网站
- 电脑怎么编程:电脑怎么编程网咯游戏菜单图标
- 如何写代码新手教学 如何写代码新手教学手机
- 基础编程入门教程视频 基础编程入门教程视频华
- 编程演示:编程演示浦丰投针过程
- 乐高编程加盟 乐高积木编程加盟
- 跟我学plc编程 plc编程自学入门视频教程
- ug编程成航林总 ug编程实战视频
- 孩子学编程的好处和坏处
- 初学者学编程该从哪里开始 新手学编程从哪里入
- 慢走丝编程 慢走丝编程难学吗
- 国内十强少儿编程机构 中国少儿编程机构十强有
- 成人计算机速成培训班 成人计算机速成培训班办
- 孩子学编程网上课程哪家好 儿童学编程比较好的
- 代码编程教学入门软件 代码编程教程