编写一个javscript函数 fn,该函数有一个参数 n(数字类型),其返回值是一个数组,该数组内是 n 个随机且不重复的整数,且整数取值范围是 [2, 32]。
最近有个比较火的文章,叫做《为什么你的前端工作经验不值钱?》 文章讲的是工作经验,并以一道简单的笔试题为例,要求代码要做到:
1. 可用(核心、基本)
2. 健壮(兼容性、边界处理、异常处理、用户输入校验等)
3. 可靠(js无强数据类型,函数返回值无法强制返回,编写代码时要求在任何情况下返回一个可靠的结果)
4. 宽容(对需求宽容、对用户宽容、对调用者宽容、对维护者宽容。大概是做苦活脏活不抱怨的意思。)
5. 精益求精(对自己不宽容,严格要求自己)
咳咳,我们回到正题。作为小白,我试着做了这道笔试题,我发现我写出可用的代码费了好多时间……果然还是需要加油。所以我写下了这篇心得。
最终优化的代码如下:
<!DOCTYPE html>
<html>
<head>
<title>returnRandomArrayFrom2to32</title>
</head>
<body>
<script type="text/javascript">
//编写一个javscript函数 fn,该函数有一个参数 n(数字类型),其返回值是一个数组,该数组内是 n 个随机且不重复的整数,且整数取值范围是 [2, 32]。
function fn(n)
{
var array = new Array();//创建一个空的数组,存储要返回的数组。
for(var i= 0; i<n; i++)
{
//获得2到32范围的随机数
var rnd = getRand(2, 32);
if(isIncluded(rnd, array))
{
i--;
//如果数组里面有这个数,让i在下一个循环不变。
//这里的i--抵消掉了循环后的i++
}
else
{
array.push(rnd);//如果数组里没有这个随机数,就允许添加进这个数组。
}
}
return array;
}
//传递一个数据类型和数组,判断数组内是否有前者。
function isIncluded(element, array)
{
for (var i = 0, len = array.length; i < len; i++)
{
if(array[i] == element)
{
return true;
}
}
return false;
}
//传入一个范围,返回一个该范围的随机数。
function getRand(min, max)
{
//如果输入的min比max大,将它们的值交换
if( max< min)
{
var n = max;
max = min;
min = n;
}
//注意是max-min+1而不是max-min哦
return Math.floor(Math.random()* (max-min+1) ) + min;
}
//输出
demo = fn(31);//如果参数是比31还要大的数,可是会无限循环的哦。
for(var i= 0; i<demo.length; i++)
{
console.log(i+":"+demo[i]);
}
</script>
</body>
</html>
其实我没看思路前的代码是这样的:
<!DOCTYPE html>
<html>
<head>
<title>returnRandomArrayFrom2to32</title>
</head>
<body>
<script type="text/javascript">
//编写一个javscript函数 fn,该函数有一个参数 n(数字类型),其返回值是一个数组,该数组内是 n 个随机且不重复的整数,且整数取值范围是 [2, 32]。
function fn(n)
{
var array = new Array(n);
var notRepeat = new Array(30);
for(var i= 0; i<n; i++)
{
array[i] = Math.floor(Math.random()*30)+2;
for(var j= 0; j<notRepeat.length; j++)
{
if(array[i]==notRepeat[j])
{
array[i] = Math.floor(Math.random()*30)+2;
j-=1;
}
}
notRepeat.push(array[i]);
}
return array;
}
demo = fn(32);
for(var i= 0; i<demo.length; i++)
{
console.log(i+":"+demo[i]);
}
</script>
</body>
</html>
首先我这个代码,确实可用,但是可读性很差。思路是直接创建一个长度为n的数组,以及一个数组notReapeat(用于存储已经赋值了且不重复的元素)。然后循环赋值一个随机数,对这个随机数循环,发现与notReapeat的元素有相同的就再次赋值随机数,并把本次循环再来一遍,直到这个循环结束。因为循环结束了,说明没有出现相同的元素,所以notRepeat就可以加上这个元素了,然后下一次外面循环就更新了notRepeat。不停循环,复制
我不得不说,这代码真的是烂,连我都很难说清楚这个代码的具体逻辑,算法复杂,可读性差,且这个notRepeat是多余的,push方法都忘了用等。所以我还是要好好努力,多做点算法题。
知识点总结:
- Array.Prototype.includes:这是js自带的新方法,可以判断一个数组里面是否有某个数,会返回boolean。但是,因为低版本的浏览器不支持,最好做好自己写一个。
- Math.random的范围是[0,1)的小数。
- [min, max]的长度是max-min+1,而不是max-min
- 一定要想好思路才开始写代码。最好先提炼一份伪代码。不然就会像我一开始写的代码一样,看不懂,运行慢。
- 代码能包装成函数尽量写出函数,这样你的代码更有可读性。