JavaScript 随机抽取不重复的数组元素,你真的会吗?

HTML5学堂-码匠:从JavaScript数组(Array)中随机抽取不重复的元素,构成新数组(Array),拥有多种方法,来看看你用的方法性能如何?

JavaScript 随机抽取不重复的数组元素,你真的会吗?

谁说我写的方法性能不好了,给我出来,哼!!!

JavaScript 效果的功能需求

从一个JavaScript数组当中,随机抽取数个元素,构成新数组,要求这些元素不能重复。(即随机获取不重复的数组元素)

相关说明:在此处依照“构思难度”和“性能”两方面出发,提供了四种不同的实现方法。

方法1:较为“传统”的实现方法

基本实现思路

从第二次随机抽取的元素开始,需要将抽取的元素与当前新数组的已抽取元素相比较,如果相同,则重新抽取,并再次执行比较的操作。

JavaScript 代码实现

var arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

var arrNum=[];

var ranNum = 5;

for(var i = 0; i < ranNum; i++) {

arrNum[i] = Math.floor(Math.random() * 10);

if(i > 0) {

for(var j = 0; j < i; j++) {

if(arrNum[j] == arrNum[i]) {

i--;

break;

}

}

}

}

方法实现难度与执行效率分析

在代码编写方面,涉及循环语句和条件语句的多层嵌套,这种方法比较容易想到,但编写复杂度较高,执行效率上来说很低,随着元素的抽取,要比较的次数越来越多,“失败的抽取”概率越来越大,整体效率低下。

JavaScript 随机抽取不重复的数组元素,你真的会吗?

这个方法的性能也太糟糕了吧~真不如我写的!!!

方法2:标记法 / 自定义属性法

基本实现思路

当获取新元素时,为该元素添加一个属性标记,再抽取一个元素之后,先判断是否有属性标记,如果已被标记,则说明该元素已被抽取,此时重新抽取。

JavaScript 代码实现

var arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

var ranNum = 5;

var hash = {};

var result = [];

while(ranNum > 0) {

var ran = Math.floor(Math.random() * arr.length);

if (!hash[ran]) {

hash[ran] = 1;

result.push(ran);

ranNum--;

};

}

方法实现难度与执行效率分析

和第一种方法相比,编写复杂度较低,只需要使用循环语句和条件语句配合即可实现,节省了第一种方法中依次比较的步骤,但依旧存在“失败抽取”的现象,而且失败抽取的概率没有发生任何变化。

JavaScript 随机抽取不重复的数组元素,你真的会吗?

文章干货太多,先看看妹子,养养眼~~~不错,继续往下看文章

方法3:交换法

第三种方法是自己最喜欢的(“交换法”的名字是自己起的),也是自己在使用的。

基本实现思路

该方法的基本原理是,在抽取一个元素之后,将该元素与数组末端的最后一个元素交换,然后将数组最后一个元素扔掉。

随着比较的进行,每次被抽取的元素都被交换到了数组末端,再被扔掉,数组长度也越来越短。

方法实现难度与执行效率分析

这种方法不太容易想到,但它的编写复杂度是三者中最低的,而性能也是最好的,由于每次比较之后,都将已抽取的元素删除了,因此并不会出现失败的抽取,更不需要做什么比较了。

实现思路演示

JavaScript 随机抽取不重复的数组元素,你真的会吗?

JavaScript 随机抽取不重复的数组元素 - 交换法

JavaScript 代码实现 - 第一步

var arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

var result = [ ];

var ranNum = 5;

for (var i = 0; i < ranNum; i++) {

var ran = Math.floor(Math.random() * arr.length);

result.push(arr[ran]);

var center = arr[ran];

arr[ran] = arr[arr.length - 1];

arr[arr.length - 1] = center;

arr = arr.slice(0, arr.length - 1);

};

JavaScript 代码实现 - 优化

仔细观察第一步的代码中,有哪些步骤是不必须的?

交换法中,最重要的是两个点,第一,每次当前元素会被数组末尾元素所替代。第二,每次随机数的范围越来越小,数组长度越来越短。

也就是说,我们只要保证当前元素被末尾元素替代,并不断减小随机数范围,“数组长度”和“数组末尾的元素值”是可以忽略的。

去掉“数组长度”的控制,并且稍加修改代码,就变成了这样:

var arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

var result = [ ];

var ranNum = 5;

for (var i = 0; i < ranNum; i++) {

var ran = Math.floor(Math.random() * (arr.length - i));

result.push(arr[ran]);

var center = arr[ran];

arr[ran] = arr[arr.length - i - 1];

arr[arr.length - i - 1] = center;

};

之后,我们取消“处理数组末尾的元素”,代码会得到进一步优化(优化后的代码如下)。

JavaScript 随机抽取不重复的数组元素,你真的会吗?

这个方法真牛逼呀~~~吓死宝宝了

优化后的JavaScript成品代码

var arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

var result = [ ];

var ranNum = 5;

for (var i = 0; i < ranNum; i++) {

var ran = Math.floor(Math.random() * (arr.length - i));

result.push(arr[ran]);

arr[ran] = arr[arr.length - i - 1];

};

优化后的实现逻辑

JavaScript 随机抽取不重复的数组元素,你真的会吗?

JavaScript 随机抽取不重复的数组元素 - 交换法

方法4:随用随删

基本实现思路

利用splice方法,将抽取到的元素从数组当中删除掉,并利用splice方法返回值,将抽取到的元素存储(push)到结果数组当中。

JavaScript 代码实现

var arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

var result = [];

var ranNum = 5;

for (var i = 0; i < ranNum; i++) {

var ran = Math.floor(Math.random() * arr.length);

result.push(arr.splice(ran, 1)[0]);

};

方法实现难度与执行效率分析

该方法和第三种方法类似,但在实现方式上有所不同,也很快捷方便,每次抽取只需要进行截取和“抽取元素”的存取即可。并不会有重复的“失败抽取”和比较。

JavaScript 随机抽取不重复的数组元素,你真的会吗?

我看上你这个方法了~~

额外要说的

为何要那么重点讲解第三种方法呢?

JavaScript 随机抽取不重复的数组元素,你真的会吗?

一般人我不告诉他~~~~

JavaScript 随机抽取不重复的数组元素,你真的会吗?

HTML5学堂(码匠) - https://weixin.mj216.com/

  • 9
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
第1章 页面特效 1.1 HTML页面反向显示 1.2 页面自动最大化 1.3 页面自动刷新 1.4 页面的后退、刷新、前进 1.5保护网页源代码 1.6 保护自己的网页不被放入框架 1.7 保护自己的网页不被放入框架 1.8 打印页面的出错原因 1.9 当前网页调用其他网页 1.10 倒计时载入页面 1.11 定义网页的关键字 1.12 进入页面同时弹出欢迎对话框 1.13 禁止网页另存 1.14 禁止页面加入缓存 1.15 离开页面时弹出对话框 1.16 判断页面是否添加了W3C声明 1.17 屏蔽网页中的脚本 1.18 以频道模式打开页面 1.19 自动识别网页类型 1.20 在网页中动态添加Script脚本 1.21 用JavaScript随机修改页面的标题 1.22 判断网页加载完毕 1.23 嵌入网页的播放器 1.24 设置指定网页为主页 1.25 使用JavaScript传递页面参数 1.26 页面被冻结 第 2章 按钮特效 2.1 页面刷新按钮 2.2 按回车调用登录按钮 2.3 动态创建按钮 2.3 平面按钮 2.4 按钮的嵌入效果 2.5 按钮改变状态栏信息 2.6 定义按钮的热键 2.7 取得控件的绝对位置 2.8 删除时的确认提 示 2.9 按钮只能单击一次 2.10 防止按钮连击 2.11 图片式按钮 2.12 文字显示在按钮底部 2.13 选择不同的列表项就显示不同的按钮 2.14 使用按钮控制文本渐变 2.15 翻页效果的公告栏 2.16 动态设置控件的事件 第3章 字符串文本和输入框特效 3.1 只带下划线的输入框 3.2 限定文本框可输入字符数 3.3 文字过长的省略号 3.4 输出26个英文字母 3.5 首字母变为大写 3.6 textarea自适应文字行数 3.7 禁止文本框的拷贝和粘贴 3.8 控制两个文本框只输其一 3.9 判断编辑器中是否包含特殊字符 3.10 判断文本中回车的数量 3.11 判断字符串中有多少汉字 3.12 去除字符串的前后空格 3.13 刷新时清空所有文本框 3.14 随意改变大小的文本框 3.15 文本框的自动全选 3.16 文本框滚动导航 3.17 按钮获取焦点 3.18 文本框获取焦点弹出下拉框 3.19 文本框简单的单击效果 3.20 文字的打字效果 3.21 文字滚动 3.22 文字滑动 3.23 文字跳动特效 3.24 荧光效果的文本 3.25 文字逐个闪亮-霓虹灯效果 3.26 旋转式的变色文字特效 3.27 黑客帝国中的字符下落效果 3.28 获取表单中文本框的个数 3.29 光标停在文字最后 3.30 分行取textarea中的值 3.31 自动插入文本 3.32 选取textarea的指定行 3.33 文本放大镜 3.34 文本框的默认输入法 3.35 文本框显示网页中选中的内容 3.36 文字的垂直滚动 3.37 文字幻灯片 3.38 随机动态文字效果 3.39 实现textarea的自动滚动 3.40 使用marquee实现文字上下滚动 3.41 类似安装效果的textarea滚动 3.42 始终显示在最顶端的文本 3.43 JavaScript过滤SQL注入字符 3.44 textarea内实现行的翻页效果 3.45 textarea中的文本插入 3.46 查找两段文本中相同的词句 3.47 自动保存网页输出的文本 3.48 文本编辑器 第4章 鼠标特效 4.1 禁用鼠标右键 4.2 使鼠标滚轮失效 4.3 状态栏显示鼠标位置 4.4 点击鼠标右键到指定页 4.5 鼠标放到图片上显示另外一张图片 4.6 鼠标形状定义大全 4.7 鼠标移入移出时颜色变化 4.8 跟随鼠标的文字 4.9 跟随鼠标的彩色文字 4.10 跟随鼠标的魔法文字 4.11 跟随鼠标的星星 4.12 跟随鼠标的旋转背景 4.13 图片跟随鼠标 4.14 围绕鼠标的文本 4.15 鼠标旁边的提示信息 4.16 鼠标移到下拉框时自动全部打开 4.17 checkbox鼠标移入移出的特效 第5章 层和框架的特效 5.1 div层提示效果 5.2 层自动滚动到最底端 5.3 div的自动滚动 5.4 div的折迭效果 5.5 圆角div 5.6 动态添加iframe框架 5.7 用层实现长文章分页 5.8 iframe自适应高度 5.9 类似MSN的消息提示 5.10 只打印iframe的内容 第6章 下拉列表特效 6.1 下拉框实现多选 6.2 实现两个select的同步 6.3 被选中的列表项下次不能再选 6.4 不带滚动条的select 6.5 从一个下拉列表往另一个下拉列表添加内容 6.6 改变列表项的上下顺序

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值