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 相关文章推荐
7款风格新颖的jQuery/CSS3菜单导航分享
Apr 23 Javascript
JQuery中dataGrid设置行的高度示例代码
Jan 03 Javascript
js获取鼠标点击的位置实现思路及代码
May 09 Javascript
jQuery filter函数使用方法
May 19 Javascript
15个jquery常用方法、小技巧分享
Jan 13 Javascript
jQuery如何获取动态添加的元素
Jun 24 Javascript
对Js OOP编程 创建对象的一些全面理解
Jul 26 Javascript
微信公众号开发 自定义菜单跳转页面并获取用户信息实例详解
Dec 08 Javascript
Base64(二进制)图片编码解析及在各种浏览器的兼容性处理
Feb 09 Javascript
微信小程序 MD5的方法详解及实例代码
Mar 10 Javascript
JS中通过url动态获取图片大小的方法小结(两种方法)
Oct 31 Javascript
javascript实现京东快递单号的查询效果
Nov 30 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使用内置函数生成图片的方法详解
2016/05/09 PHP
php上传图片并给图片打上透明水印的代码
2010/06/07 Javascript
基于Jquery插件开发之图片放大镜效果(仿淘宝)
2011/11/19 Javascript
js时间日期和毫秒的相互转换
2013/02/22 Javascript
node.js学习总结之调式代码的方法
2014/06/25 Javascript
js对象基础实例分析
2015/01/13 Javascript
扒一扒JavaScript 预解释
2015/01/28 Javascript
Javascript基于对象三大特性(封装性、继承性、多态性)
2016/01/04 Javascript
jquery拖拽排序简单实现方法(效果增强版)
2016/02/16 Javascript
jQuery获取字符串中出现最多的数
2016/02/22 Javascript
利用jquery实现瀑布流3种案例
2016/09/18 Javascript
AngularJS控制器controller给模型数据赋初始值的方法
2017/01/04 Javascript
详解vue 计算属性与方法跟侦听器区别(面试考点)
2018/04/23 Javascript
详解Nuxt.js部署及踩过的坑
2018/08/07 Javascript
vue从一个页面跳转到另一个页面并携带参数的解决方法
2019/08/12 Javascript
JavaScript实现刮刮乐效果
2020/11/01 Javascript
详解vite+ts快速搭建vue3项目以及介绍相关特性
2021/02/25 Vue.js
python脚本设置系统时间的两种方法
2016/02/21 Python
python 查找字符串是否存在实例详解
2017/01/20 Python
详解Python多线程Selenium跨浏览器测试
2017/04/01 Python
Python实现可设置持续运行时间、线程数及时间间隔的多线程异步post请求功能
2018/01/11 Python
Vue的el-scrollbar实现自定义滚动
2018/05/29 Python
详解python配置虚拟环境
2019/04/08 Python
详解如何设置Python环境变量?
2019/05/13 Python
python实现证件照换底功能
2019/08/20 Python
详解python3中用HTMLTestRunner.py报ImportError: No module named 'StringIO'如何解决
2019/08/27 Python
python文字转语音的实例代码分析
2019/11/12 Python
Python urlencode和unquote函数使用实例解析
2020/03/31 Python
Python使用Paramiko控制liunx第三方库
2020/05/20 Python
Python调用飞书发送消息的示例
2020/11/10 Python
CSS3中Transition动画属性用法详解
2016/07/04 HTML / CSS
初三开学计划书
2014/04/27 职场文书
政法干警核心价值观心得体会
2014/09/11 职场文书
出纳试用期工作总结2015
2015/05/28 职场文书
会计主管竞聘书
2015/09/15 职场文书
详解Go语言运用广度优先搜索走迷宫
2021/06/23 Python