javascript实现数组内值索引随机化及创建随机数组的方法


Posted in Javascript onAugust 10, 2015

本文实例讲述了javascript实现数组内值索引随机化及创建随机数组的方法。分享给大家供大家参考。具体如下:

今天在QW交流群里看到有同学讨论使数组随机化的问题,其中给出的算法很不错,让我想起了之前自己实现过的不怎么“漂亮”的方法。想想我们有时候在繁忙的写业务代码时只是为了实现其功能,并未花太大心思去思考是否有更好的实现方法。

就这个数组问题(随即排序一个数组里的值,返回一个新数组)来说,我以前的实现方法是这样的:

function randArr(arr) {
 var ret = [],
 obj = {},
 i = arr.length,
 l = i,
 n;
 while (--i >= 0) {
  n = Math.floor( Math.random() * l );
  if (obj[n] === void 0) {
   ret[ret.length] = obj[n] = arr[n];
  } else {
   i++;
  }
 }
 return ret;
}

上面的代码会工作,但并不是一个好的算法,它打算执行“原数组的长度”次循环,每一次循环会随机取一个原数组中的索引,然后判断该索引是否已被取过,如果没有则把该索引的值放入新数组中,如果取过则把自减键 i 自增1(目的是重复该次循环直到取到另一个未取过的索引)。这样的方法的性能是很看人品的,原因相信看到这种思路的同学都已明白了。

现在给出群里那位同学的算法:

function randArr(arr) {
 var ret = [],
 i = arr.length,
 n;
 arr = arr.slice(0);
 while (--i >= 0) {
  n = Math.floor( Math.random() * i);
  ret[ret.length] = arr.splice(n, 1)[0];
 }
 return ret;
}

这是一个相当巧妙的算法,在每次循环中取一个随机的索引后,并把它的值从数组中删除,这样,如果后面依然随机取到这个索引,这个索引就已经不再是上一次取到的值了,而且随机数的取值范围会根据数组的长度的减小而减小,这样就能一次性循环一定的次数而得到理想的结果。

还看到了一个改进版的,是考虑到了对数组的删除操作而导致的些许性能问题,运用了JK大的洗牌算法,即把每一次删除操作改为了位置替换操作(取到的该索引的值和当前自减键 i 对应的值进行互换),这样对整个数组的影响是最小的,还是放代码吧:

function randArr(arr) {
 var ret = [],
 i = arr.length,
 n;
 arr = arr.slice(0);
 
 while (--i >= 0) {
  n = Math.floor( Math.random() * i);
  ret[ret.length] = arr[n];
  arr[n] = arr[i];
 }
 return ret;
}

最后给出一个“创建值为min~max间的随机数组”的方法,算法原理同上面的差不多:

function makeRandArr(min, max) {
 var ret = [],
 obj = {},
 n;
 for (; max >= min; max--) {
  n = Math.ceil( Math.random() * (max - min) ) + min;
  ret[ret.length] = obj[n] || n;
  obj[n] = obj[max] || max;
 }
 return ret;
}

希望本文所述对大家的javascript程序设计有所帮助。

Javascript 相关文章推荐
js常用代码段收集
Oct 28 Javascript
jQuery学习笔记之创建DOM元素
Jan 19 Javascript
JS实现可点击展开与关闭的左侧广告代码
Sep 02 Javascript
jquery.validate提示错误信息位置方法
Jan 22 Javascript
jQuery添加和删除输入文本框标签代码
May 20 Javascript
BootStrap中的table实现数据填充与分页应用小结
May 26 Javascript
JavaScript的setter与getter方法
Nov 29 Javascript
vue.js 实现点击按钮动态添加li的方法
Sep 07 Javascript
详解微信小程序自定义组件的实现及数据交互
Jul 22 Javascript
关于vue路由缓存清除在main.js中的设置
Nov 06 Javascript
js判断在哪个浏览器打开项目的方法
Jan 21 Javascript
Openlayers实现扩散的动态点(水纹效果)
Aug 17 Javascript
jQuery解决input超多的表单提交
Aug 10 #Javascript
jQuery实现的图文高亮滚动切换特效实例
Aug 10 #Javascript
jQuery基于ajax实现带动画效果无刷新柱状图投票代码
Aug 10 #Javascript
javascript中caller和callee详解
Aug 10 #Javascript
jQuery实现购物车表单自动结算效果实例
Aug 10 #Javascript
javascript中$(function() {});写与不写有哪些区别
Aug 10 #Javascript
jQuery中$(function() {});问题详解
Aug 10 #Javascript
You might like
Fatal error: Call to undefined function curl_init()解决方法
2010/04/09 PHP
php 图片加水印与上传图片加水印php类
2010/05/12 PHP
Codeigniter整合Tank Auth权限类库详解
2014/06/12 PHP
Laravel中注册Facades的步骤详解
2016/03/16 PHP
PHP实现可自定义样式的分页类
2016/03/29 PHP
浅谈PHP各环境下的伪静态配置
2019/03/13 PHP
phpstorm最新激活码分享亲测phpstorm2020.2.3版可用
2020/11/22 PHP
让div层随鼠标移动的实现代码 ie ff
2009/12/18 Javascript
基于jquery的自定义鼠标提示效果 jquery.toolTip
2010/11/14 Javascript
js使用eval解析json(js中使用json)
2014/01/17 Javascript
15款jQuery分布引导插件分享
2015/02/04 Javascript
JQuery显示、隐藏div的几种方法简明总结
2015/04/16 Javascript
jQuery实现点击查看大图并以弹框的形式居中
2016/08/08 Javascript
js方法数据验证的简单实例
2016/09/17 Javascript
jQuery使用正则表达式替换dom元素标签用法示例
2017/01/16 Javascript
jQuery与vue实现拖动验证码功能
2018/01/30 jQuery
微信小程序用户信息encryptedData详解
2018/08/24 Javascript
使用koa-log4管理nodeJs日志笔记的使用方法
2018/11/30 NodeJs
深入了解JavaScript 防抖和节流
2019/09/12 Javascript
[03:09]2014DOTA2国际邀请赛 Mushi前队友送上祝福
2014/07/12 DOTA
[40:05]LGD vs Winstrike 2018国际邀请赛小组赛BO2 第二场 8.17
2018/08/18 DOTA
python增加矩阵维度的实例讲解
2018/04/04 Python
Keras在训练期间可视化训练误差和测试误差实例
2020/06/16 Python
python中常见错误及解决方法
2020/06/21 Python
局域网标准
2016/09/10 面试题
Linux管理员面试题 Linux admin interview questions
2016/07/08 面试题
个人找工作求职简历的自我评价
2013/10/20 职场文书
大学生两会精神学习心得体会
2014/03/10 职场文书
2014年保卫工作总结
2014/12/05 职场文书
西安大雁塔导游词
2015/02/10 职场文书
男方婚前保证书
2015/02/28 职场文书
网站文案策划岗位职责
2015/04/14 职场文书
2016年学校综治宣传月活动总结
2016/03/16 职场文书
导游词之澳门妈祖庙
2019/12/19 职场文书
详解TypeScript的基础类型
2022/02/18 Javascript
Ruby使用Mysql2连接操作MySQL
2022/04/19 Ruby