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 一行代码,轻松搞定浮动快捷留言-V2升级版
Apr 02 Javascript
javascript中的变量是传值还是传址的?
Apr 19 Javascript
再谈querySelector和querySelectorAll的区别与联系
Apr 20 Javascript
LABjs、RequireJS、SeaJS的区别
Mar 04 Javascript
Linux下编译安装php libevent扩展实例
Feb 14 Javascript
网页中JS函数自动执行常用三种方法
Mar 30 Javascript
JS 动态判断PC和手机浏览器实现代码
Sep 21 Javascript
详解react-native-fs插件的使用以及遇到的坑
Sep 12 Javascript
jQuery实现简单的回到顶部totop功能示例
Oct 16 jQuery
JS加密插件CryptoJS实现AES加密操作示例
Aug 16 Javascript
ES6知识点整理之模块化的应用详解
Apr 15 Javascript
vue 判断两个时间插件结束时间必选大于开始时间的代码
Nov 04 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 会话(session 时间设定)使用入门代码
2008/06/05 PHP
PHP取整数函数常用的四种方法小结
2012/07/05 PHP
在PHP模板引擎smarty生成随机数的方法和math函数详解
2014/04/24 PHP
PHP常用处理静态操作类
2015/04/03 PHP
php生成word并下载代码实例
2019/03/15 PHP
PHP实现Snowflake生成分布式唯一ID的方法示例
2020/08/30 PHP
JavaScript 异步方法队列链实现代码分析
2010/06/05 Javascript
小试JQuery的AutoComplete插件
2011/05/04 Javascript
js中top的作用深入剖析
2014/03/04 Javascript
js数组中如何随机取出一个值
2014/06/13 Javascript
javascript使用正则获取url上的某个参数
2014/09/04 Javascript
javascript框架设计读书笔记之模块加载系统
2014/12/02 Javascript
JavaScript简单表格编辑功能实现方法
2015/04/16 Javascript
js窗口震动小程序分享
2016/11/28 Javascript
Bootstrap弹出框modal上层的输入框不能获得焦点问题的解决方法
2016/12/13 Javascript
vue watch监听对象及对应值的变化详解
2018/02/24 Javascript
jquery实现动态创建form并提交的方法示例
2019/05/27 jQuery
jquery实现两个div中的元素相互拖动的方法分析
2020/04/05 jQuery
python实现给字典添加条目的方法
2014/09/25 Python
python实现在控制台输入密码不显示的方法
2015/07/02 Python
python 出现SyntaxError: non-keyword arg after keyword arg错误解决办法
2017/02/14 Python
Python zip()函数用法实例分析
2018/03/17 Python
使用python实现离散时间傅里叶变换的方法
2019/09/02 Python
在python中利用try..except来代替if..else的用法
2019/12/19 Python
一篇文章带你搞定Ubuntu中打开Pycharm总是卡顿崩溃
2020/11/02 Python
日本钓鱼渔具和户外用品网上商店:naturum
2016/08/07 全球购物
德国黑胶唱片、街头服装及运动鞋网上商店:HHV
2018/08/24 全球购物
应届毕业生就业自荐信
2013/10/26 职场文书
餐饮加盟计划书
2014/01/10 职场文书
小学生田径运动会广播稿
2014/09/11 职场文书
离婚协议书包括哪些内容
2014/10/16 职场文书
2016春节慰问信范文
2015/03/25 职场文书
2015年营业员工作总结
2015/04/23 职场文书
新闻稿格式范文
2015/07/18 职场文书
女方家长婚礼致辞
2015/07/27 职场文书
二手手机买卖合同范本(2019年版)
2019/10/28 职场文书