4

I'm taking online JavaScript courses and I'm curious about one of the tasks:

We'r provided with an initial array (the first argument in the destroyer function), followed by one or more arguments. We have to remove all elements from the initial array that are of the same value as these arguments.

Here's my solution, but it doesn't works:

 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);

I was able to find a solution, however it doesn't makes any sense to me, that's why I'm posting this question; can you please tell me why the following code works:

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);

Thank you for the heads up!

2
  • 1
    The function in filter needs to return some value. If it’s truthy (e.g. true), the element is kept, if it’s falsy (e.g. false), it’s removed. You’re only returning false or undefined (automatically) which is falsy. Commented Nov 16, 2016 at 11:19
  • The function passed to the filter method must return true if you want to retain the element. If it only returns false it will remove everything. Not returning a value is treated as if returning false. Commented Nov 16, 2016 at 11:20

5 Answers 5

2

You might do the same job with a relatively simple code by utilizing Array.prototype.reduce() as follows;

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));

or in 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));

Sign up to request clarification or add additional context in comments.

Comments

2

filter is an Array native function. It creates a new array with all elements that pass a given test. The test function must return a boolean value, if true that value is not filtered out and if false, it is filtered out.

Go through the docs: Filter- Array

The correct solution that you have posted, has a valid test function for filtering the given array, that returns true and false, for the specific use case (here being the logic of eliminating numbers provided as arguments).

Your implementation misses returning true (which is returning undefined, a falsey value in Javscript, hence all of the values are filtered out and you get an empty array.

Note: true here refers to all truthy values in JS and false refers to all falsy values in JS.

Comments

2

You code is not working because you are not returning true.

Array.filter expects a boolean value as return value. If true, it will add to resulting dataset. If false, is will skip.

Since you are not returning anything, it returns undefined as default and undefined is falsey. Hence your return array would be blank.

As per MDN,

filter() calls a provided callback function once for each element in an array, and constructs a new array of all the values for which callback returns a value that coerces to true.

Comments

2

Read what Rajesh wrote, it is easy to understand how filter() works.

Also you do not actually need a helper function. This code is more than enough:
Edit: even less code as suggested by 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);

1 Comment

Thanks for credit. You can replace return filterArr.indexOf(v)>-1 as your callback for filter.
1

The filter callback has to return a boolean to either keep the element or to drop it so true says that the value passed your check.

A detailed description of the filter prototype can be found here.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.