我参加了在线JavaScript课程,我很好奇其中一项任务:
我们提供了一个初始数组(驱逐舰函数中的第一个参数),后跟一个或多个参数。我们必须从初始数组中删除与这些参数具有相同值的所有元素。
这是我的解决方案,但它不起作用:
function destroyer(arr) {
// Separating the array from the numbers, that are for filtering;
var filterArr = [];
for (var i = 1; i < arguments.length; i++) {
filterArr.push(arguments[i]);
}
// This is just to check if we got the right numbers
console.log(filterArr);
// Setting the parameters for the filter function
function filterIt(value) {
for (var j = 0; j < filterArr.length; j++) {
if (value === filterArr[j]) {
return false;
}
}
}
// Let's check what has been done
return arguments[0].filter(filterIt);
}
destroyer([1, 2, 3, 1, 2, 3], 2, 3);
&#13;
我能找到一个解决方案,但这对我没有任何意义,这就是我发布这个问题的原因;你能告诉我为什么以下代码有效:
function destroyer(arr) {
// Separating the array from the numbers, that are for filtering;
var filterArr = [];
for (var i = 1; i < arguments.length; i++) {
filterArr.push(arguments[i]);
}
// This is just to check if we got the right numbers
console.log(filterArr);
// Setting the parameters for the filter function
function filterIt(value) {
for (var j = 0; j < filterArr.length; j++) {
if (value === filterArr[j]) {
return false;
}
// This true boolean is what makes the code to run and I can't // understand why. I'll highly appreciate your explanations.
}
return true;
}
// Let's check what has been done
return arguments[0].filter(filterIt);
}
destroyer([1, 2, 3, 1, 2, 3], 2, 3);
&#13;
谢谢您的提醒!
答案 0 :(得分:2)
您的代码无效,因为您没有返回true
。
Array.filter
期望一个布尔值作为返回值。如果true
,它将添加到结果数据集中。如果false
,则会跳过。
由于您没有返回任何内容,因此默认返回undefined
,undefined
为假。因此,您的返回数组将为空白。
根据MDN,
filter()为数组中的每个元素调用一次提供的回调函数,并构造一个新数组,其中所有值的回调都返回一个强制为true的值。
答案 1 :(得分:2)
filter
是一个Array本机函数。它创建一个新数组,其中包含通过给定测试的所有元素。测试函数必须返回一个布尔值,如果true
该值未被滤除,如果false
,则将其过滤掉。
浏览文档: Filter- Array
您发布的正确解决方案具有用于过滤给定数组的有效测试函数,该函数返回true
和false
,用于特定用例(这里是消除数字的逻辑)作为参数)。
你的实现错过了返回true
(返回undefined
,这是Javscript中的假值,因此所有值都被过滤掉了,你得到一个空数组。
注意: true
这里指的是JS中的所有truthy值,false
指的是JS中的所有虚假值。
答案 2 :(得分:2)
阅读Rajesh写的内容,很容易理解filter()
的工作原理。
此外,您实际上并不需要辅助功能。
这段代码绰绰有余:
编辑 甚至更少的代码,如Rajesh
function destroyer(arr) {
for (var i = 1, filterArr = []; i < arguments.length; i++) {
filterArr.push(arguments[i]);
}
return arguments[0].filter(function(v) {
return filterArr.indexOf(v)===-1
});
}
var result = destroyer([1, 2, 3, 1, 2, 5, 3], 2, 3);
console.log(result);
答案 3 :(得分:2)
使用Array.prototype.reduce()
,您可以使用相对简单的代码执行相同的工作,如下所示;
ES6
var destroyer = (a,...f) => a.reduce((p,c) => f.includes(c) ? p : p.concat(c),[]);
console.log(destroyer([1, 2, 3, 1, 2, 3], 2, 3));
或在ES5中
function destroyer(a){
var f = Array.prototype.slice.call(arguments,1);
return a.reduce(function(p,c){
return f.indexOf(c) !== -1 ? p : p.concat(c);
},[]);
}
console.log(destroyer([1, 2, 3, 1, 2, 3], 2, 3));
答案 4 :(得分:1)
过滤器回调必须返回一个布尔值来保留元素或删除它,所以true表示该值通过了你的检查。
可以在此处找到过滤器原型的详细说明。
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter