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栏目列表隐藏/显示简单实现
Apr 03 Javascript
JS辨别访问浏览器判断是android还是ios系统
Aug 19 Javascript
jQuery实现精美的多级下拉菜单特效
Mar 14 Javascript
在JavaScript中访问字符串的子串
Jul 07 Javascript
Angular的事件和表单详解
Dec 26 Javascript
js获取地址栏参数的两种方法
Jun 27 Javascript
js微信应用场景之微信音乐相册案例分享
Aug 11 Javascript
微信小程序实现验证码获取倒计时效果
Feb 08 Javascript
vue.js select下拉框绑定和取值方法
Mar 03 Javascript
vue+express 构建后台管理系统的示例代码
Jul 19 Javascript
原生JS forEach()和map()遍历的区别、兼容写法及jQuery $.each、$.map遍历操作
Feb 27 jQuery
vue3实现v-model原理详解
Oct 09 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
解析左右值无限分类的实现算法
2013/06/20 PHP
php绘制圆形的方法
2015/01/24 PHP
解决yii2左侧菜单子级无法高亮问题的方法
2016/05/08 PHP
php实现生成code128条形码的方法详解
2017/07/19 PHP
PHP时间日期增减操作示例【date strtotime实现加一天、加一月等操作】
2018/12/21 PHP
javascript 精粹笔记
2010/05/09 Javascript
jQuery .tmpl(), .template()学习资料小结
2011/07/18 Javascript
查找iframe里元素的方法可传参
2013/09/11 Javascript
Javascript排序算法之计数排序的实例
2014/04/05 Javascript
js控制容器隐藏出现防止样式变化的两种方法
2014/04/25 Javascript
node.js不得不说的12点内容
2014/07/14 Javascript
JavaScript使用setTimeout实现延迟弹出警告框的方法
2015/04/07 Javascript
js实现具有高亮显示效果的多级菜单代码
2015/09/01 Javascript
使用bootstrap validator的remote验证代码经验分享(推荐)
2016/09/21 Javascript
JavaScript登录记住密码操作(超简单代码)
2017/03/22 Javascript
Node.js v8.0.0正式发布!看看带来了哪些主要新特性
2017/06/02 Javascript
原生JS实现瀑布流插件
2018/02/06 Javascript
JS实现单张或多张图片持续无缝滚动的示例代码
2020/05/10 Javascript
详解vue v-model
2020/08/31 Javascript
在vue项目中封装echarts的步骤
2020/12/25 Vue.js
[02:23]2014DOTA2国际邀请赛中国战队回顾
2014/08/01 DOTA
Python使用pandas处理CSV文件的实例讲解
2018/06/22 Python
代码详解django中数据库设置
2019/01/28 Python
Python过滤掉numpy.array中非nan数据实例
2020/06/08 Python
python爬虫请求头设置代码
2020/07/28 Python
python os.rename实例用法详解
2020/12/06 Python
如何利用python生成MD5并去重
2020/12/07 Python
HTML5的download属性详细介绍和使用实例
2014/04/23 HTML / CSS
李维斯牛仔裤荷兰官方网站:Levi’s NL
2020/08/23 全球购物
程序运行正确, 但退出时却"core dump"了,怎么回事
2014/02/19 面试题
科技之星事迹材料
2014/06/02 职场文书
办公室务虚会发言材料
2014/10/20 职场文书
优秀党支部申报材料
2014/12/24 职场文书
聘任通知书
2015/09/21 职场文书
用Python的绘图库(matplotlib)绘制小波能量谱
2021/04/17 Python
Python道路车道线检测的实现
2021/06/27 Python