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 相关文章推荐
jQuery AnythingSlider滑动效果插件
Feb 07 Javascript
DIV始终居中的js代码
Feb 17 Javascript
jQuery实现的进度条效果
Jul 15 Javascript
jQuery对html元素的取值与赋值实例详解
Dec 18 Javascript
jquery.cookie实现的客户端购物车操作实例
Dec 24 Javascript
javascript实现PC网页里的拖拽效果
Mar 14 Javascript
jQuery UI结合Ajax创建可定制的Web界面
Jun 22 Javascript
JS原型链怎么理解
Jun 27 Javascript
jQuery插件jqGrid动态获取列和列字段的方法
Mar 03 Javascript
微信小程序实现animation动画
Jan 26 Javascript
实现jquery放大镜的两种方法
Feb 22 jQuery
Vue 监听列表item渲染事件方法
Sep 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
模拟OICQ的实现思路和核心程序(一)
2006/10/09 PHP
php ob_flush,flush在ie中缓冲无效的解决方法
2010/05/09 PHP
浅谈Laravel队列实现原理解决问题记录
2017/08/19 PHP
JavaScript 学习笔记一些小技巧
2010/03/28 Javascript
defer属性导致引用JQuery的页面报“浏览器无法打开网站xxx,操作被中止”错误的解决方法
2010/04/27 Javascript
javascript中日期转换成时间戳的小例子
2013/03/21 Javascript
event对象获取方法总结在google浏览器下测试
2013/11/03 Javascript
jQuery使用之设置元素样式用法实例
2015/01/19 Javascript
JQuery使用index方法获取Jquery对象数组下标的方法
2015/05/18 Javascript
JavaScript中Boolean对象的属性解析
2015/10/21 Javascript
JS正则匹配URL网址的方法(可匹配www,http开头的一切网址)
2017/01/06 Javascript
详解使用 Node.js 开发简单的脚手架工具
2018/06/08 Javascript
百度小程序自定义通用toast组件
2019/07/17 Javascript
js实现时间日期校验
2020/05/26 Javascript
Postman参数化实现过程及原理解析
2020/08/13 Javascript
Python抓取京东图书评论数据
2014/08/31 Python
Python调用ctypes使用C函数printf的方法
2017/08/23 Python
Python实现一个服务器监听多个客户端请求
2018/04/12 Python
使用Python进行体育竞技分析(预测球队成绩)
2019/05/16 Python
python实现最大子序和(分治+动态规划)
2019/07/05 Python
Python实现的远程文件自动打包并下载功能示例
2019/07/12 Python
在pycharm中为项目导入anacodna环境的操作方法
2020/02/12 Python
Django-xadmin后台导入json数据及后台显示信息图标和主题更改方式
2020/03/11 Python
HTML5是什么 HTML5是什么意思 HTML5简介
2012/10/26 HTML / CSS
Mountain Warehouse澳大利亚官网:欧洲家庭户外品牌倡导者
2016/11/20 全球购物
澳洲小众品牌的集合网站:BNKR
2018/02/23 全球购物
美容师的职业规划书
2013/12/27 职场文书
仓库管理专业个人的自我评价
2013/12/30 职场文书
关于迟到的检讨书
2014/01/26 职场文书
材料加工工程求职信
2014/02/19 职场文书
技校毕业生自荐信
2014/06/03 职场文书
车间安全生产标语
2014/06/06 职场文书
nginx常用命令放入shell脚本详解
2021/03/31 Servers
golang 实现对Map进行键值自定义排序
2021/04/28 Golang
Android开发EditText禁止输入监听及InputFilter字符过滤
2022/06/10 Java/Android
windows server2012 R2下安装PaddleOCR服务的的详细步骤
2022/09/23 Servers