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 相关文章推荐
jquery.lazyload  实现图片延迟加载jquery插件
Feb 06 Javascript
jquery checkbox,radio是否选中的判断代码
Mar 20 Javascript
JavaScript 错误处理与调试经验总结
Aug 10 Javascript
Javascript 页面模板化很多人没有使用过的方法
Jun 05 Javascript
JavaScript获取鼠标移动时的坐标(兼容IE8、chome谷歌、Firefox)
Sep 13 Javascript
浅谈javascript构造函数与实例化对象
Jun 22 Javascript
前端js文件合并的三种方式推荐
May 19 Javascript
jstree单选功能的实现方法
Jun 07 Javascript
详解使用VueJS开发项目中的兼容问题
Aug 02 Javascript
微信小程序录音实现功能并上传(使用node解析接收)
Feb 26 Javascript
js实现拾色器插件(ColorPicker)
May 21 Javascript
Vue全家桶入门基础教程
May 14 Vue.js
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
PHP初学者常见问题集合 修正版(21问答)
2010/03/23 PHP
PHP中的Streams详细介绍
2014/11/12 PHP
PHP导出带样式的Excel示例代码
2016/08/28 PHP
PHP中如何使用Redis接管文件存储Session详解
2018/11/28 PHP
学习jquery之一
2007/04/27 Javascript
ExtJs grid行 右键菜单的两种方法
2010/06/19 Javascript
jquery实现的让超出显示范围外的导航自动固定屏幕最顶上
2011/09/22 Javascript
jQuery on()方法使用技巧详解
2015/04/16 Javascript
jQuery实现分章节锚点“回到顶部”动画特效代码
2015/10/23 Javascript
fullCalendar中文API官方文档
2017/02/07 Javascript
javascript 初学教程及五子棋小程序的简单实现
2017/07/04 Javascript
Vue.js devtool插件安装后无法使用的解决办法
2017/11/27 Javascript
Bootstrap fileinput 上传新文件移除时触发服务器同步删除的配置
2018/10/08 Javascript
Vue项目pdf(base64)转图片遇到的问题及解决方法
2018/10/19 Javascript
微信小程序的mpvue框架快速上手指南
2019/05/15 Javascript
利用JavaScript的Map提升性能的方法详解
2019/08/14 Javascript
jQuery实现图片随机切换、抽奖功能(实例代码)
2019/10/23 jQuery
webpack4 配置 ssr 环境遇到“document is not defined”
2019/10/24 Javascript
详解Vue template 如何支持多个根结点
2020/02/10 Javascript
JSON stringify方法原理及实例解析
2020/10/23 Javascript
详解Python中的相对导入和绝对导入
2017/01/06 Python
Python版名片管理系统
2018/11/30 Python
Python提取频域特征知识点浅析
2019/03/04 Python
python主线程与子线程的结束顺序实例解析
2019/12/17 Python
如何基于Python创建目录文件夹
2019/12/31 Python
解释下面关于J2EE的名词
2013/11/15 面试题
工业自动化毕业生自荐信范文
2014/01/04 职场文书
获奖的大学生创业计划书
2014/01/05 职场文书
工作表现自我评价
2014/02/08 职场文书
平面设计求职信
2014/03/10 职场文书
办公用房租赁协议书
2014/11/29 职场文书
七夕情人节问候语
2015/11/11 职场文书
2016年幼儿园教师师德承诺书
2016/03/25 职场文书
门面租赁合同范文
2019/08/06 职场文书
六年级情感作文之500字
2019/10/23 职场文书
Redis模仿手机验证码发送的实现示例
2021/11/02 Redis