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静态页面传值的三种方法分享
Nov 12 Javascript
js中使用replace方法完成某个字符的转换
Aug 20 Javascript
node.js中的fs.symlinkSync方法使用说明
Dec 15 Javascript
jquery插件jquery.dragscale.js实现拖拽改变元素大小的方法(附demo源码下载)
Feb 25 Javascript
JavaScript驾驭网页-获取网页元素
Mar 24 Javascript
深入理解js数组的sort排序
May 28 Javascript
JavaWeb表单及时验证功能在输入后立即验证(含用户类型,性别,爱好...的验证)
Jun 09 Javascript
关于vue-router的那些事儿
May 23 Javascript
javascript实现文本框标签验证的实例代码
Oct 14 Javascript
Node.js使用supervisor进行开发中调试的方法
Mar 26 Javascript
Angular封装表单控件及思想总结
Dec 11 Javascript
微信小程序实现签字功能
Dec 23 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
根德Grundig S400/S500/S700电路分析
2021/03/02 无线电
PHP动态创建Web站点的方法
2011/08/14 PHP
介绍一些PHP判断变量的函数
2012/04/24 PHP
php实现根据词频生成tag云的方法
2015/04/17 PHP
PHP异常处理Exception类
2015/12/11 PHP
PHP利用二叉堆实现TopK-算法的方法详解
2017/04/24 PHP
提高Laravel应用性能方法详解
2019/06/24 PHP
设置下载不需要倒计时cookie(倒计时代码)
2008/11/19 Javascript
node.js入门教程迷你书、node.js入门web应用开发完全示例
2014/04/06 Javascript
js实现checkbox全选和反选示例
2014/05/01 Javascript
jQuery中用dom操作替代正则表达式
2014/12/29 Javascript
Javascript 拖拽雏形中的一些问题(逐行分析代码,让你轻松了拖拽的原理)
2015/01/23 Javascript
jQuery使用元素属性attr赋值详解
2015/02/27 Javascript
ECMAScript6函数剩余参数(Rest Parameters)
2015/06/12 Javascript
JavaScript 正则表达式中global模式的特性
2016/02/25 Javascript
Node.js 日志处理模块log4js
2016/08/28 Javascript
JS输出空格的简单实现方法
2016/09/08 Javascript
利用Mongoose让JSON数据直接插入或更新到MongoDB
2017/05/03 Javascript
用vue-cli开发vue时的代理设置方法
2018/09/20 Javascript
JS实现根据数组对象的某一属性排序操作示例
2019/01/14 Javascript
vue项目打包之后背景样式丢失的解决方案
2019/01/17 Javascript
在微信小程序中渲染HTML内容3种解决方案及分析与问题解决
2020/01/12 Javascript
JS算法教程之字符串去重与字符串反转
2020/12/15 Javascript
[01:11:35]Liquid vs LGD 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
利用Python求阴影部分的面积实例代码
2018/12/05 Python
Python3.4学习笔记之列表、数组操作示例
2019/03/01 Python
Tensorflow实现部分参数梯度更新操作
2020/01/23 Python
Python和Bash结合在一起的方法
2020/11/13 Python
python实现银行账户系统
2021/02/22 Python
HTML5+CSS3实现无插件拖拽上传图片(支持预览与批量)
2017/01/05 HTML / CSS
Speedo速比涛德国官方网站:世界领先的泳装品牌
2019/08/26 全球购物
国际政治个人自荐信范文
2013/11/26 职场文书
先进集体获奖感言
2014/02/13 职场文书
基层党建工作宣传标语
2014/06/24 职场文书
4s店销售经理岗位职责
2014/07/19 职场文书
2015年度个人思想工作总结
2015/04/08 职场文书