Reputation: 177
Here is what I have to do:
You will be provided with an initial array (the first argument in the destroyer function), followed by one or more arguments. Remove all elements from the initial array that are of the same value as these arguments.
My code:
function destroyer(arr) {
for(i=1; i < arguments.length; i++) {
x = arr.filter(filterer);
}
function filterer(val) {
return val !== arguments[i];
}
return x;
}
destroyer([1, 2, 3, 1, 2, 3], 2, 3);
But it doesn't work properly and returns the initial array not the filtered one. Where is my mistake?
Upvotes: 1
Views: 77
Reputation: 386634
Basically, you have two issues,
arguments[i]
in wrong content, in a callback of the filter function,
function destroyer(arr) { function filterer(val) { // <--------------------+ return val !== arguments[i]; // | // ^^^^^^^^^^^^ this points to --+ } for(i=1; i < arguments.length; i++) { x = arr.filter(filterer); } return x; }
no assignment of the result for further filtering.
Solution
take a function with a closure over the test value and return a function for further testing in the filter method.
use a variable with arr
as start value and assign the filter result. Then return this value at the end.
function destroyer(arr) {
function filterer(testValue) { // take arguments[i] value
return function (val) { // return function as callback
return val !== testValue; // use testValue instead of arguments[i]
}
}
var x = arr // assign arr as start value for filtering
for (var i = 1; i < arguments.length; i++) {
x = x.filter(filterer(arguments[i])); // use filterer with a parameter
}
return x; // return result
}
console.log(destroyer([1, 2, 3, 1, 2, 3], 2, 3));
Upvotes: 3
Reputation: 3047
make a copy of arguments object. As Abdennour said, scope of arguments object changes for filterer.
Also, make copy of input array and keep on filtering from that array only.. otherwise your result will just be filtered for last argument.
function destroyer(arr) {
var copy = arguments;
var x = arr;
for(i=1; i < copy.length; i++) {
x = x.filter(filterer);
}
function filterer(val) {
return val !== copy[i];
}
return x;
}
destroyer([1, 2, 3, 1, 2, 3], 2, 3);
Upvotes: 1
Reputation: 93213
arguments
scope is changed .
You want to use arguments[i]
inside function filterer(val) {return val !== arguments[i];}
as it is the arguments of the parent function which is destroyer
.
If so , use filterer
as arrow function to keep the scope of arguments
.
function destroyer(arr) {
const filterer = (val) => { // 👈🏼 ⚠️ This is an arrow function
return val !== arguments[i]; // ⬅️ "arguments" refers now to "destroyer()" args
}
for(i=1; i < arguments.length; i++) {
x = arr.filter(filterer);
}
return x;
}
destroyer([1, 2, 3, 1, 2, 3], 2, 3);
Upvotes: 1