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 相关文章推荐
Flash+XML滚动新闻代码 无图片 附源码下载
Nov 22 Javascript
javascript深入理解js闭包
Jul 03 Javascript
javascript设置金额样式转换保留两位小数示例代码
Dec 04 Javascript
js监听鼠标事件控制textarea输入字符串的个数
Sep 29 Javascript
moment.js轻松实现获取当前日期是当年的第几周
Feb 05 Javascript
Jquery使用css方法改变样式实例
May 18 Javascript
JavaScript中的getMilliseconds()方法使用详解
Jun 10 Javascript
JavaScript获取当前url根目录(路径)
Jun 17 Javascript
适用于手机端的jQuery图片滑块动画
Dec 09 Javascript
Canvas实现动态的雪花效果
Feb 13 Javascript
ES6学习教程之块级作用域详解
Oct 09 Javascript
js实现浏览器打印功能的示例代码
Jul 15 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的5个入手程序
2006/11/23 PHP
用 PHP5 轻松解析 XML
2006/12/04 PHP
php Notice: Undefined index 错误提示解决方法
2010/08/29 PHP
php使用smtp发送支持附件的邮件示例
2014/04/13 PHP
php中fgetcsv()函数用法实例
2014/11/28 PHP
PHP实现过滤各种HTML标签
2015/05/17 PHP
PHP基于递归算法解决兔子生兔子问题
2018/05/11 PHP
兼容IE和FF的图片上传前预览js代码
2013/05/28 Javascript
javascript实现控制浏览器全屏
2015/03/30 Javascript
javascript限制文本框输入值类型的方法
2015/05/07 Javascript
js过滤HTML标签完整实例
2015/11/26 Javascript
基于JavaScript如何实现ajax调用后台定义的方法
2015/12/29 Javascript
原生js制作日历控件实例分享
2016/04/06 Javascript
js获取当前年月日-YYYYmmDD格式的实现代码
2016/06/01 Javascript
Sequelize中用group by进行分组聚合查询
2016/12/12 Javascript
浅谈原生JS实现jQuery的animate()动画示例
2017/03/08 Javascript
ES6中module模块化开发实例浅析
2017/04/06 Javascript
JS原生带缩略图的图片切换效果
2018/10/10 Javascript
vue实现浏览器全屏展示功能
2019/11/27 Javascript
Python代码的打包与发布详解
2014/07/30 Python
Python内置的HTTP协议服务器SimpleHTTPServer使用指南
2016/03/30 Python
在win和Linux系统中python命令行运行的不同
2016/07/03 Python
Django卸载之后重新安装的方法
2017/03/15 Python
用TensorFlow实现lasso回归和岭回归算法的示例
2018/05/02 Python
django自带的server 让外网主机访问方法
2018/05/14 Python
利用Anaconda简单安装scrapy框架的方法
2018/06/13 Python
Django框架 查询Extra功能实现解析
2019/09/04 Python
Python通过递归获取目录下指定文件代码实例
2019/11/07 Python
vscode配置anaconda3的方法步骤
2020/08/08 Python
python中_del_还原数据的方法
2020/12/09 Python
serialVersionUID具有什么样的特征
2014/02/20 面试题
五十岁生日宴会答谢词
2014/01/15 职场文书
旅游饭店管理专业自荐书
2014/06/28 职场文书
关于迟到的检讨书
2015/05/06 职场文书
家长会开场白和结束语
2015/05/29 职场文书
2016党风廉政建设心得体会范文
2016/01/25 职场文书