JavaScript随机打乱数组顺序之随机洗牌算法


Posted in Javascript onAugust 02, 2016

假如有一个数组是这样子:

var arr1 = ["a", "b", "c", "d"];

如何随机打乱数组顺序,也即洗牌。

有一个比较广为传播的简单随机算法:

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

实际证明上面这个并不完全随机。

随便一搜网上太多这种东西了,看一下stackoverflow上的一个高分回答,答案出自github上。

knuth-shuffle
The Fisher-Yates (aka Knuth) shuffle for Browser and Node.JS

下面一起看看上面说的这个算法,代码如下:

/*jshint -W054 */
(function (exports) {
'use strict';
// http://stackoverflow.com/questions/2450954/how-to-randomize-shuffle-a-javascript-array
function shuffle(array) {
var currentIndex = array.length
, temporaryValue
, randomIndex
;
// While there remain elements to shuffle...
while (0 !== currentIndex) {
// Pick a remaining element...
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex -= 1;
// And swap it with the current element.
temporaryValue = array[currentIndex];
array[currentIndex] = array[randomIndex];
array[randomIndex] = temporaryValue;
}
return array;
}
exports.knuthShuffle = shuffle;
}('undefined' !== typeof exports && exports || 'undefined' !== typeof window && window || global));

作者推荐使用浏览器写法:

(function () {
'use strict';
var a = [2,11,37,42]
, b
;
// The shuffle modifies the original array
// calling a.slice(0) creates a copy, which is assigned to b
b = window.knuthShuffle(a.slice(0));
console.log(b);
}());

Nodejs:

npm install -S knuth-shuffle
(function () {
'use strict';
var shuffle = require('knuth-shuffle').knuthShuffle
, a = [2,11,37,42]
, b
;
// The shuffle modifies the original array
// calling a.slice(0) creates a copy, which is assigned to b
b = shuffle(a.slice(0));
console.log(b);
}());

还有其它从这个算法中变形去的,比如下面这个for循环的。其它的就不说了。

/**
* Randomize array element order in-place.
* Using Durstenfeld shuffle algorithm.
*/
function shuffleArray(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;
}

使用ES2015(ES6)

Array.prototype.shuffle = function() {
let m = this.length, i;
while (m) {
i = (Math.random() * m--) >>> 0;
[this[m], this[i]] = [this[i], this[m]]
}
return this;
}

使用:

[1, 2, 3, 4, 5, 6, 7].shuffle();

发现中文搜索随机算法一大堆,但究竟是不是完全随机,效率和兼容性都有待考究,建议后面如果有需要用到随机打乱数组元素,可以用上面这个。

Javascript 相关文章推荐
Some tips of wmi scripting in jscript (1)
Apr 03 Javascript
js克隆对象、数组的常用方法介绍
Sep 26 Javascript
javascript运行机制之this详细介绍
Feb 07 Javascript
浅谈JavaScript中运算符的优先级
Jul 07 Javascript
Angular.js与Bootstrap相结合实现表格分页代码
Apr 12 Javascript
jquery实现左右轮播切换效果
Jan 01 jQuery
Vue 2.0 中依赖注入 provide/inject组合实战
Jun 20 Javascript
vue router动态路由设置参数可选问题
Aug 21 Javascript
解决微信小程序中的滚动穿透问题
Sep 16 Javascript
vue el-table实现行内编辑功能
Dec 11 Javascript
el-form 多层级表单的实现示例
Sep 10 Javascript
一文搞懂redux在react中的初步用法
Jun 09 Javascript
AngularJS基础 ng-mouseleave 指令详解
Aug 02 #Javascript
js数组常用操作方法小结(增加,删除,合并,分割等)
Aug 02 #Javascript
实现React单页应用的方法详解
Aug 02 #Javascript
AngularJS基础 ng-mouseenter 指令示例代码
Aug 02 #Javascript
使用JavaScript判断手机浏览器是横屏还是竖屏问题
Aug 02 #Javascript
AngularJS ng-mousedown 指令
Aug 02 #Javascript
JS从数组中随机取出几个数组元素的方法
Aug 02 #Javascript
You might like
php采用ajax数据提交post与post常见方法总结
2014/11/10 PHP
php获取远程文件大小
2015/10/20 PHP
PHP使用数组实现矩阵数学运算的方法示例
2017/05/29 PHP
JQuery开发的数独游戏代码
2010/10/29 Javascript
基于jquery自己写tab滑动门(通用版)
2012/10/30 Javascript
ext combobox动态加载数据库数据(附前后台)
2014/06/17 Javascript
jquery使用remove()方法删除指定class子元素
2015/03/26 Javascript
JavaScript自定义函数实现查找两个字符串最长公共子串的方法
2016/11/24 Javascript
JavaScript获取URL参数的方法之一
2017/03/24 Javascript
Bootstrap实现的经典栅格布局效果实例【附demo源码】
2017/03/30 Javascript
原生js FileReader对象实现图片上传本地预览效果
2020/03/27 Javascript
用Webpack构建Vue项目的实践
2017/11/07 Javascript
ajax请求+vue.js渲染+页面加载的示例
2018/02/11 Javascript
AngularJS下$http服务Post方法传递json参数的实例
2018/03/29 Javascript
在vue项目中使用codemirror插件实现代码编辑器功能
2019/08/27 Javascript
element-ui 本地化使用教程详解
2019/10/28 Javascript
在vue-cli3中使用axios获取本地json操作
2020/07/30 Javascript
maptalks+three.js+vue webpack实现二维地图上贴三维模型操作
2020/08/10 Javascript
[05:09]第二届DOTA2亚洲邀请赛决赛日比赛集锦:iG 3:0 OG夺冠
2017/04/05 DOTA
python模拟Django框架实例
2016/05/17 Python
Python-while 计算100以内奇数和的方法
2019/06/11 Python
Python GUI编程 文本弹窗的实例
2019/06/11 Python
Python3.8对可迭代解包的改进及用法详解
2019/10/15 Python
python实现两个字典合并,两个list合并
2019/12/02 Python
python3 xpath和requests应用详解
2020/03/06 Python
DataFrame.groupby()所见的各种用法详解
2020/06/14 Python
Python中全局变量和局部变量的理解与区别
2021/02/07 Python
即时搜索数百万张门票:SeatsForEveryone.com
2018/08/26 全球购物
Fnac西班牙官网:法国文化和电子产品零售商
2021/03/14 全球购物
行政专员岗位职责
2014/01/02 职场文书
珍珠奶茶店创业计划书
2014/01/11 职场文书
企业办公室岗位职责
2014/03/12 职场文书
新闻学专业求职信
2014/07/28 职场文书
四风问题个人剖析材料
2014/10/07 职场文书
MySQL中几种插入和批量语句实例详解
2021/09/14 MySQL
Vue深入理解插槽slot的使用
2022/08/05 Vue.js