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 相关文章推荐
JavaScript 申明函数的三种方法 每个函数就是一个对象(一)
Dec 04 Javascript
JavaScript 实现打印,打印预览,打印设置
Dec 30 Javascript
玩转JavaScript OOP - 类的实现详解
Jun 08 Javascript
jQuery实现的选择商品飞入文本框动画效果完整实例
Aug 10 Javascript
Node+Express+MongoDB实现登录注册功能实例
Apr 23 Javascript
浅谈Angular 中何时取消订阅
Nov 22 Javascript
bootstrap select2插件用ajax来获取和显示数据的实例
Aug 09 Javascript
Vue-cli3简单使用(图文步骤)
Apr 30 Javascript
微信小程序事件 bindtap bindinput代码实例
Aug 26 Javascript
JS字符串补全方法padStart()和padEnd()
May 27 Javascript
vue中解决微信html5原生ios虚拟键返回不刷新问题
Oct 20 Javascript
JavaScript实现下拉列表
Jan 20 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
PHP常用技术文之文件操作和目录操作总结
2014/09/27 PHP
php中base64_decode与base64_encode加密解密函数实例
2014/11/24 PHP
php获取今日开始时间和结束时间的方法
2017/02/27 PHP
PHP单例模式数据库连接类与页面静态化实现方法
2019/03/20 PHP
比较搞笑的js陷阱题
2010/02/07 Javascript
javascript 另一种图片滚动切换效果思路
2012/04/20 Javascript
3分钟写出来的Jquery版checkbox全选反选功能
2013/10/23 Javascript
Bootstrap安装环境配置教程分享
2016/05/27 Javascript
基于jQuery实现选项卡效果
2017/01/04 Javascript
jQuery EasyUI ProgressBar进度条组件
2017/02/28 Javascript
jQuery实现分页功能(含ajax请求、后台数据、附完整demo)
2017/04/03 jQuery
微信小程序实战之自定义抽屉菜单(7)
2017/04/18 Javascript
ES6新特性五:Set与Map的数据结构实例分析
2017/04/21 Javascript
package.json文件配置详解
2017/06/15 Javascript
JavaScript操作文件_动力节点Java学院整理
2017/06/30 Javascript
Javascript之图片的延迟加载的实例详解
2017/07/24 Javascript
基于VUE实现的九宫格抽奖功能
2018/09/30 Javascript
微信小程序页面间值传递的两种方法
2018/11/26 Javascript
Vue动态修改网页标题的方法及遇到问题
2019/06/09 Javascript
Nodejs封装类似express框架的路由实例详解
2020/01/05 NodeJs
vue如何使用外部特殊字体的操作
2020/07/30 Javascript
批处理与python代码混合编程的方法
2016/05/19 Python
Python读写txt文本文件的操作方法全解析
2016/06/26 Python
python 查找字符串是否存在实例详解
2017/01/20 Python
python2 对excel表格操作完整示例
2020/02/23 Python
Python读取二进制文件代码方法解析
2020/06/22 Python
地球上最先进的胡子和头发修剪器:Bevel
2018/01/23 全球购物
英国女性时尚精品店:THE DRESSING ROOM
2018/05/23 全球购物
英国顶尖手表珠宝品牌独家授权经销商:HS Johnson
2020/10/28 全球购物
中英文自我评价语句
2013/12/20 职场文书
早读课迟到检讨书
2014/09/25 职场文书
罚款通知怎么写
2015/04/22 职场文书
宇宙与人观后感
2015/06/05 职场文书
车间安全生产管理制度
2015/08/06 职场文书
学长教您写论文:经验总结
2019/07/09 职场文书
Python实现byte转integer
2021/06/03 Python