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 相关文章推荐
动态加载iframe
Jun 16 Javascript
jquery入门—编写一个导航条(可伸缩)
Jan 07 Javascript
JavaScript实现文字与图片拖拽效果的方法
Feb 16 Javascript
4种JavaScript实现简单tab选项卡切换的方法
Jan 06 Javascript
jquery中用函数来设置css样式
Dec 22 Javascript
jQuery基本选择器和层次选择器学习使用
Feb 27 Javascript
微信小程序 flex实现导航实例详解
Apr 26 Javascript
Vue单文件组件的如何使用方式介绍
Jul 28 Javascript
解析Vue 2.5的Diff算法
Nov 28 Javascript
vue引入axios同源跨域问题
Sep 27 Javascript
小程序实现图片移动缩放效果
May 26 Javascript
vue 导航菜单刷新状态不消失,显示对应的路由界面操作
Aug 06 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
IIS+fastcgi下PHP运行超时问题的解决办法详解
2013/06/20 PHP
深入理解PHP中的global
2014/08/19 PHP
PHP实现清除MySQL死连接的方法
2016/07/23 PHP
PHP编程快速实现数组去重的方法详解
2017/07/22 PHP
设定php简写功能的方法
2019/11/28 PHP
JSON 编辑器实现代码
2009/12/06 Javascript
jQuery的Ajax时无响应数据的解决方法
2010/05/25 Javascript
js自定义事件代码说明
2011/01/31 Javascript
使用jquery.upload.js实现异步上传示例代码
2014/07/29 Javascript
Nodejs学习笔记之Stream模块
2015/01/13 NodeJs
遍历json获得数据的几种方法小结
2017/01/21 Javascript
微信JSAPI Ticket接口签名详解
2020/06/28 Javascript
AngularJS通过ng-Img-Crop实现头像截取的示例
2017/08/17 Javascript
JS实现的全排列组合算法示例
2017/10/09 Javascript
基于jQuery实现的设置文本区域的光标位置
2018/06/15 jQuery
jQuery实现input输入框获取焦点与失去焦点时提示的消失与显示功能示例
2019/05/27 jQuery
解析原来浏览器原生支持JS Base64编码解码
2019/08/12 Javascript
微信小程序使用蓝牙小插件
2019/09/23 Javascript
编写一个javascript元循环求值器的方法
2020/04/14 Javascript
解决Ant Design Modal内嵌Form表单initialValue值不动态更新问题
2020/10/29 Javascript
Python下rrdtool模块的基本使用方法
2015/11/13 Python
python将字符串list写入excel和txt的实例
2019/07/20 Python
利用ImageAI库只需几行python代码实现目标检测
2019/08/09 Python
html5 worker 实例(二) 图片变换效果
2013/06/24 HTML / CSS
html5 div布局与table布局详解
2016/11/16 HTML / CSS
高中毕业自我鉴定
2013/12/19 职场文书
单位成立周年感言
2014/01/26 职场文书
青年教师培训方案
2014/02/06 职场文书
医学检验专业自荐信
2014/09/18 职场文书
国庆节促销广告语2014
2014/09/19 职场文书
2016教师国培研修感言
2015/12/08 职场文书
Nginx下配置Https证书详细过程
2021/04/01 Servers
老生常谈 使用 CSS 实现三角形的技巧(多种方法)
2021/04/13 HTML / CSS
Go语言带缓冲的通道实现
2021/04/26 Golang
深入理解MySQL中MVCC与BufferPool缓存机制
2022/05/25 MySQL
Redis基本数据类型Zset有序集合常用操作
2022/06/01 Redis