写在前面:
很早之前在简书写过几篇关于随机数的文章之前写的很乱,现在重新整理一下这些知识点。本文包含了如下这些知识点:js生成随机数,生成指定范围的随机数,获得不重复随机数组。
js生成随机数。
Math.random()——生成大于等于0.0且小于1.0的一个随机数;
通常我们生成随机数都是使用这个方法,这个方法返回值是一个伪随机选择的数,该值大于等于0.0且小于1.0,即取值范围是[0.0,1.0)的左闭右开区间,在该范围内(近似)均匀分布。
下面有张动态图栗子,可以看一下。
Math.floor(Math.random()*20)——取0~20之间的随机整数:
Math.floor(x)——使后面括号内的x(任意数值或表达式),生成一个小于等于 x,且与 x 最接近的整数。
Math.floor(x),可以简单理解为下舍入。这里有几个栗子帮助理解,//后面是输出的内容:
document.write(Math.floor(0.60) + "<br />")//0 document.write(Math.floor(0.40) + "<br />")//0 document.write(Math.floor(5) + "<br />")//5 document.write(Math.floor(5.1) + "<br />")//5 document.write(Math.floor(-5.1) + "<br />")//-6 document.write(Math.floor(-5.9))//-6
解析上面Math.floor(Math.random()*20)的栗子:
1.通过Math.random()生成0-1之间的随机数
2.然后乘以20,就是取从0~20间的随机数,注意这里并不是整数。这里的范围可以改变,只要改后面那个数字为50,、8,就可以变成0~50,0~80之间的随机数。
3.Math.floor(),使括号里面的(Math.random()乘以20)这个表达式,下舍入,生成为一个整数。
上面两个方法的demo动态图。
文末有demo链接,可以把代码复制回去,自己试试
生成指定范围的随机数(从任意值到任意值)
这里是从任意值开始,我们刚才取的随机数都是从0开始。但是有些场景可能需要我们取一个指定范围的随机数,比如20-30,80-120等等。
这里有一个公式:Math.floor(Math.random()*(max-min+1)+min);
ps: max - 范围内的最大值,min - 单位内的最小值
按照这个公式来,就没错了,下面是demo栗子。
值得注意的是:
如果是负数范围的随机数,要进行符号转换的,比如--30(这里是说减去三十。),转换符号后变成+。不转换符号,会出现报错!
Math.floor(Math.random()*(-10--30+1)+-30)//错误 Math.floor(Math.random()*(-10+30+1)-30);//正确。
生成指定范围的随机数的栗子:
生成指定范围的随机数的栗子
获得不重复的随机数组。
获得不重复随机数组的方法非常多,这里就介绍一种:使用indexOf()的方法来去重,然后通过push()方法来添加数组。
push() 方法的作用:
push() 方法可向数组的末尾添加一个或多个元素,并返回新的长度。
indexOf()方法的定义及介绍:
来自W3C
看完了还是一脸懵逼,到底跟随机数组去重有什么关系??
这里有一句特别关键:
注释:如果要检索的字符串值没有出现,则该方法返回 -1。
依靠这句注释,通过if条件判断,我们就可以做出随机数组去重的功能。
代码:
//num是一个数组,randomNum是一个随机数值。 while (num.length<3){//num.length代表数组的长度,当数组的长度不再满足小于3,跳出循环 var randomNum=Math.floor(Math.random()*9);//获得在0-9之间的随机数 if (num.indexOf(randomNum)<0){ //判断randomNum之前有没有在数组里面,如果没有,就添加进去,如果有,重新循环。 num.push(randomNum); // 将randomNum这个随机数,添加到num这个数组里面。 } console.log(num); }
代码思路:
1.先限定数组的长度,否则就成死循环了。
2.获得一个随机数
3.判断是否已经在数组里面,如果没有,就执行if下面的函数。
4.没有出现这个随机数,indexOf()这个方法会返回-1,这是判断条件的依据。
5.当随机数达到三个了就跳出循环。此时num数组已经去重完毕。
代码执行演示:
以下是演示的一个栗子,当数组里面已经有6了,再随机到6的时候,就会跳过push,直到随机到不重复的。
ps:indexOf()这个方法去重效率到后期偏低,仅适用于数据量比较小的时候,因为后期数据量大的话,数组中每一个都进行依次比较的话,时间方面会花很长时间。