Reputation: 1913
The goal is to create a function called destroyer that filters all arguments after an initial array argument out of the array.
I'm not very good at functional programming yet so my answer doesn't work, but I'm getting some fish results that I don't understand. Here's my function:
function destroyer(arr) {
var count = 1;
var result = arr;
return result.reduce(function(val){
if (count < arguments.length){
console.log('count is ' + count);
console.log("filtering " + arguments[count]);
result = result.filter(function(val){val!=arguments[count]});
count += 1;
return result;
}
else {
return result;
}
}, count);
}
Given destroyer([1, 2, 3, 1, 2, 3], 2, 3);
, this evaluates to []
, whereas it should return [1, 1]
My console logs the following:
"count is 1"
"filtering 1"
"count is 2"
"filtering 1"
"count is 3"
"filtering 1,2,3,1,2,3"
What I don't understand:
< arguments.length
(which is 3), not <=
destroyer([1, 2, 3, 1, 2, 3], 2, 3);
, why isn't arguments[count] (which should be limited from 1 - 2) returning the console log "filtering 2" ... "filtering 3" ... (and nothing else... I have no clue why the last log is coming up).Upvotes: 1
Views: 72
Reputation: 442
My solution:
function removeAll(_arr, _rem)
{
while(_arr.indexOf(_rem) !== -1)
{
var i = _arr.indexOf(_rem);
_arr.splice(i,1);
}
return _arr;
}
function destroyer(_arr, _remA, _remB)
{
var arr = removeAll(_arr, _remA);
arr = removeAll(arr, _remB);
return arr;
}
var arr = destroyer([1,2,3,1,2,3], 2, 3);
console.log(arr);
document.getElementById('divOut').innerHTML = 'destroyer([1,2,3,1,2,3], 2, 3) -> ' + JSON.stringify(arr);
<div id='divOut'></div>
though I would prefer to send an array of what to 'destroy' (/remove) as follows:
function removeAll(_arr, _rem)
{
while(_arr.indexOf(_rem) !== -1)
{
var i = _arr.indexOf(_rem);
_arr.splice(i,1);
}
return _arr;
}
function destroyer(_arr, _remArray)
{
var arr = _arr.splice(0); // clone array
for(var c = 0, length = _remArray.length; c < length; c++)
{
arr = removeAll(arr, _remArray[c]);
}
return arr;
}
var arr = destroyer([1,2,3,4,5,1,2,3,4,5], [2,3,5]);
console.log(arr);
document.getElementById('divOut').innerHTML = 'destroyer([1,2,3,4,5,1,2,3,4,5], [2,3,5]) -> ' + JSON.stringify(arr);
<div id="divOut"></div>
Upvotes: -1
Reputation: 5183
The issue here is that you have a nested function inside a function and the value of the arguments
object will be different inside both the closures.
I would suggest store each of them in a local variable and use instead of repeating the usage of arguments
.
I did a dry run of your code in the console, and will attach a screenshot of the values of your arguments
object and other variables for the first run for your understanding.
Notice how the value of arguments
changes before and after the return result.reduce(function(val)) {
line.
Upvotes: 2
Reputation: 906
function destroyer(arr) {
var count = 1;
var result = arr;
var args = arguments; //keep reference of original passed arguments;
return result.reduce(function(val){
//use args not arguments because here arguments
//will refer to the arguments of the inner function
if (count < args.length){
console.log('count is ' + count);
console.log("filtering " + args[count]);
result = result.filter(function(val){return val!=args[count]});
count += 1;
return result;
}
else {
return result;
}
}, count);
}
destroyer([1, 2, 3, 1, 2, 3], 2, 3);
Upvotes: 1
Reputation: 2814
I will try to help you a bit. 1) arguments are 4, not 3. Add
console.log(arguments);
console.log(arguments.length);
And you will see it yourself. First argument is acumulator for function reduce. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
Upvotes: 1