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 相关文章推荐
js 页面执行时间计算代码
Mar 04 Javascript
Bootstrap安装环境配置教程分享
May 27 Javascript
AngularJS实现表单验证功能
Jan 09 Javascript
多个上传文件用js验证文件的格式和大小的方法(推荐)
Mar 09 Javascript
bootstrap suggest搜索建议插件使用详解
Mar 25 Javascript
Vuex中mutations与actions的区别详解
Mar 01 Javascript
小程序红包雨的实现示例
Feb 19 Javascript
Vue渲染过程浅析
Mar 14 Javascript
Vue 3.0 前瞻Vue Function API新特性体验
Aug 12 Javascript
JS中的算法与数据结构之常见排序(Sort)算法详解
Aug 16 Javascript
详解如何修改 node_modules 里的文件
May 22 Javascript
小程序实现tab标签页
Nov 16 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之第四天
2006/10/09 PHP
PHP+Ajax实现无刷新分页实例详解(附demo源码下载)
2016/04/07 PHP
微信公众平台开发-微信服务器IP接口实例(含源码)
2017/03/05 PHP
PHP中关键字interface和implements详解
2017/06/14 PHP
TP5.0框架实现无限极回复功能的方法分析
2019/05/04 PHP
jquery ui resizable bug解决方法
2010/10/26 Javascript
一个轻量级的javascript库 pj介绍
2010/12/19 Javascript
jQuery中的val()示例应用
2014/02/26 Javascript
如何在node的express中使用socket.io
2014/12/15 Javascript
node.js中的fs.openSync方法使用说明
2014/12/17 Javascript
jQuery根据ID、CLASS、等获取对象的实例
2016/12/04 Javascript
js原生之焦点图转换加定时器实例
2016/12/12 Javascript
vue检测对象和数组的变化分析
2018/06/30 Javascript
JavaScript封装的常用工具类库bee.js用法详解【经典类库】
2018/09/03 Javascript
详解如何使用node.js的开发框架express创建一个web应用
2018/12/20 Javascript
微信小程序中button去除默认的边框实例代码
2019/08/01 Javascript
JavaScript和TypeScript中的void的具体使用
2019/09/12 Javascript
对layui初始化列表的CheckBox属性详解
2019/09/13 Javascript
Python的Django框架中if标签的相关使用
2015/07/15 Python
整理Python 常用string函数(收藏)
2016/05/30 Python
Python中二维列表如何获取子区域元素的组成
2017/01/19 Python
Python实现爬虫抓取与读写、追加到excel文件操作示例
2018/06/27 Python
python实现创建新列表和新字典,并使元素及键值对全部变成小写
2019/01/15 Python
Python安装第三方库攻略(pip和Anaconda)
2020/10/15 Python
matplotlib更改窗口图标的方法示例
2021/02/03 Python
纯CSS实现菜单、导航栏的3D翻转动画效果
2014/04/23 HTML / CSS
解决margin 外边距合并问题
2019/07/03 HTML / CSS
英国屋顶用品和材料超市:Roofing Supplies UK
2019/08/24 全球购物
英国奢侈品牌时尚购物平台:Farfetch(支持中文)
2020/02/18 全球购物
大学生实习证明范本
2014/09/19 职场文书
村干部四风问题整改措施
2014/09/30 职场文书
蜗居观后感
2015/06/11 职场文书
Python 把两层列表展开平铺成一层(5种实现方式)
2021/04/07 Python
java实现自定义时钟并实现走时功能
2022/06/21 Java/Android
Linux在两个服务器直接传文件的操作方法
2022/08/05 Servers
Spring boot admin 服务监控利器详解
2022/08/05 Java/Android