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 相关文章推荐
IE中createElement需要注意的一个问题
Jul 13 Javascript
基于javascipt-dom编程 table对象的使用
Apr 22 Javascript
JS中eval函数的使用示例
Jul 21 Javascript
jQuery获得内容和属性示例代码
Jan 16 Javascript
JQuery中节点遍历方法实例
May 18 Javascript
快速学习jQuery插件 Cookie插件使用方法
Dec 01 Javascript
JQuery移动页面开发之屏幕方向改变与滚屏的实现
Dec 03 Javascript
javascript自动恢复文本框点击清除后的默认文本
Jan 12 Javascript
JS中取二维数组中最大值的方法汇总
Apr 17 Javascript
jquery常用的12个小功能
Jul 22 Javascript
bootstrap 点击空白处popover弹出框隐藏实例
Jan 24 Javascript
js防抖和节流的深入讲解
Dec 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
二十行语句实现从Excel到mysql的转化
2006/10/09 PHP
PHP计算百度地图两个GPS坐标之间距离的方法
2015/01/09 PHP
浅析PHP开发规范
2018/02/05 PHP
PHP观察者模式示例【Laravel框架中有用到】
2018/06/15 PHP
php中使用array_filter()函数过滤数组实例讲解
2021/03/03 PHP
利用javascript查看html源文件
2006/11/08 Javascript
javascript multibox 全选
2009/03/22 Javascript
jquery offset函数应用实例
2012/11/14 Javascript
JavaScript中的值类型详细介绍
2014/12/29 Javascript
jQuery焦点图轮播插件KinSlideshow用法分析
2016/06/08 Javascript
pc加载更多功能和移动端下拉刷新加载数据
2016/11/07 Javascript
详解vue.js全局组件和局部组件
2017/04/10 Javascript
localstorage实现带过期时间的缓存功能
2019/06/28 Javascript
javascript设计模式 ? 状态模式原理与用法实例分析
2020/04/22 Javascript
详解JSON.stringify()的5个秘密特性
2020/05/26 Javascript
python处理大数字的方法
2015/05/27 Python
Python实现命令行通讯录实例教程
2016/08/18 Python
Pandas过滤dataframe中包含特定字符串的数据方法
2018/11/07 Python
在 Jupyter 中重新导入特定的 Python 文件(场景分析)
2019/10/27 Python
python实现秒杀商品的微信自动提醒功能(代码详解)
2020/04/27 Python
python文件读取失败怎么处理
2020/06/23 Python
详解Scrapy Redis入门实战
2020/11/18 Python
五分钟学会怎么用Pygame做一个简单的贪吃蛇
2021/01/06 Python
PyCharm Ctrl+Shift+F 失灵的简单有效解决操作
2021/01/15 Python
HTML5 HTMLCollection和NodeList的区别详解
2020/04/29 HTML / CSS
澳大利亚正品化妆品之家:Cosmetic Capital
2017/07/03 全球购物
Stubhub英国:购买体育、演唱会和剧院门票
2018/06/10 全球购物
Raffaello Network西班牙:意大利拉斐尔时尚购物网
2019/03/12 全球购物
Java里面如何创建一个内部类的实例
2015/01/19 面试题
北大研究生linux应用求职信
2013/10/29 职场文书
年终考核评语
2014/01/19 职场文书
人事助理自荐信
2014/02/02 职场文书
《花的勇气》教后反思
2014/02/12 职场文书
校园文明标语
2014/06/13 职场文书
赵氏孤儿观后感
2015/06/09 职场文书
springboot读取resources下文件的方式详解
2022/06/21 Java/Android