今天被fcc上的一个摧毁函数难住了,反复思考并调试了一个多小时才得以实现。
摧毁函数destroyer(arr,argument1,argument2,argument3,...),
其形参个数不确定,确定的是,它第一个形参是一个数组,然后其他的形参是一些值,我们的目的是要摧毁掉数组中等于其他形参的元素,最终返回一个新数组。
给定的参考方法是arr.filter(),和arguments对象;arr.filter()用于创建筛选后的新数组,arguments对象用于确定destroyer函数的形参个数(arguments.length,要在指定的函数内使用)。
首先想到的实现思路是:
arr.filter(function(element){
return argumentsArr.indexOf(element)==-1;
})
argumentsArr是什么呢?是形参中要摧毁的值,这个可以通过一个for循环来得到:
因为我们要得到一个数组,首先我们先声明一个数组,一个空数组,以便我们往里面push新元素,
var argumentsArr = [ ];
因为我们的新数组要从第二个形参开始,所以新数组的长度应该是arguments.length-1,
所以for循环应该写为:
for(i=0;i<arguments.length-1;i++){
argumentsArr.push(arguments[i+1]);//从第二项开始push,所以为i+1。
}
这时我们得到了新数组argumentsArr;
然后再来回顾第一步中的思路,缺少的argumentsArr变量已经得到,整个的题目也就得解了。
整个题目的代码如下:
function destroyer(arr){
var argumentsArr = [ ];
for(var i=0;i<arguments.length-1;i++){
argumentsArr.push(arguments[i+1]);
}
arr = arr.filter(function(element){
return argumentsArr.indexOf(element) == -1;
})
return arr;
}
那么我遇到的问题有哪些呢?为什么我在明白解题思路后几分钟就可以写好的代码,却花了一个多小时的时间去调试呢?
之前我是这么写的:
for(i=0;i<argumentsArr.length;i++){
arr.filter(function(argumentsArr[i]){
return arr.indexOf(argumentsArr[i]) == -1;
})
}
很显然,我之前把filter方法调用的函数的形参想象成argumentsArr中的元素了,而且还用了一个for循环,而且fcc中的编辑环境还一直提醒说for循环中不能有函数,实际上还是对filter函数理解不深不彻底,导致了对filter方法的错误理解。
其实arr.filter方法本身自带循环,它自己会使用我们给定的函数来测试数组中的所有元素,并创建(即返回)一个包含所有通过测试的元素的新数组(注意它并没有改变原数组)。
简单总结filter方法:
1,遍历数组中的元素
2,函数测试,检查return是否等于true;
3,返回一个包含所有通过测试的元素的新数组。