4

I'm new here and need some help with writing a function destroyer() to remove multiple values from an array.

The destroyer() function passes in an array and additional numbers as arguments. The idea is to remove the numbers from the array.

E.g.

destroyer([1, 2, 3, 1, 2, 3], 2, 3) 

Output: [1, 1]

destroyer(["tree", "hamburger", 53], "tree", 53) 

Output: ["hamburger"]

destroyer([2, 3, 2, 3], 2, 3) 

Output: []

Note: the examples only show 2 additional numbers to remove. But the function destroyer() should be able to remove any number of values (i.e. 4, 5, or 6 parameters).

However, my code does not produce the same result. Specifically, using console.log, I see that my filterer function does not loop properly.

1) Can anyone help me debug?

2) Any better way to write this function?

Thank you very much!!!

function destroyer() {

  var args = Array.prototype.slice.call(arguments); 

  var itemToRemove = args.slice(1);
  console.log(itemToRemove);
  var newArr = args[0];
  console.log(newArr);

  function filterer(value) { 

    for (var i = 0; i < itemToRemove.length; i++) {
      console.log(i);
      console.log(itemToRemove[i]);
      if (value != itemToRemove[i]) {
        return value;
      }
    } 
   }

  return newArr.filter(filterer);
}
5
  • If you told us what the criteria was for removing, instead of posting cryptic examples, it would probably be easier to help ? Commented Oct 22, 2015 at 6:12
  • In the first argument he passes an array, in the further the values he wants to remove Commented Oct 22, 2015 at 6:14
  • Do you always pass two values for removing? or it can be more? like destroyer([1, 2, 3, 1, 2, 3], 2,4, 3)? Commented Oct 22, 2015 at 6:57
  • It can be any number of values, e.g. 3 values to remove in your example. Commented Oct 22, 2015 at 7:02
  • I smell freeCodeCamp ;D Commented Jan 24, 2017 at 18:59

6 Answers 6

4

Your filterer function can be much simpler:

function filterer (value) {
    return itemToRemove.indexOf(value) === -1;
}
Sign up to request clarification or add additional context in comments.

1 Comment

@Neong, note, it can be not fast on big array, with many items to remove
0

Using Array.prototype.indexOf() can be inefficient compared to object property lookup in terms of time complexity. I would recommend looping through the additional arguments once and constructing an object with target elements to be destroyed as keys. Then you can check if a given value is a target or not within a filtering callback that you pass to Array.prototype.filter().

function destroyer() {
    var arr = arguments.length && arguments[0] || [];
    var targets = {};
    for (var i = 1; i < arguments.length; i++) {
        targets[arguments[i]] = true;
    }
    return arr.filter(function (x) {
        return targets[x] === undefined;
    });
}

One downside to this approach is that not all values in JS can be valid properties of an object, since properties must be strings. In this case, you're just using numbers as keys, and those numbers are implicitly converted to strings.

3 Comments

i think in this case better targets[arguments[i]] = true or something like and in filter function targets[x] === undefiend. because hasOwnProperty is more complex function and slowest with comparing to undefined
@Grundy Noted, I have edited the answer. Thank you for the suggestion.
Thank you Shashank and @Grundy for your help. It took me a while to understand this approach ;) Thank you for the perspective!
0

We can pass the arguments an extra parameter to our callback function in our filter() method.

function destroyer(arr) {
  return arr.filter(filterer(arguments)); // Pass arguments
}

function filterer(args) {
  return function(value) { // Actual filter function
    for (var i = 1; i < args.length; i++) {
      if (value === args[i]) // Seek
        return false; // Destroy
    }
    return true; // Otherwise keep
  };
}

This passes all 5 test cases for freeCodeCamp | Basic Algorithm Scripting | Seek and Destroy.

Comments

-1

A simple function

function filter(arr, arg1, arg2){

    var j = arr.length;
    while(j){

       if (arr.indexOf(arg1) > -1 || arr.indexOf(arg2) > -1){
          arr.splice(j - 1, 1);
       }
       j--
    }
}

6 Comments

what if should be three additional params? or four? :-)
In his requirement needs two arguments, I wrote this function for that
it just a sample, i think. also why you do two indexOf on every loop iteration, instead just testing array element and do splice if it equal arg1 or arg2?
I added another answer below
Sorry I wasn't clear but it can be any number of values to be removed -- 2, 3, 4, 5 etc.
|
-1

For multiple arguments

A simple function

function filter(){
    var j = -1; 
    for(var i = 1; i < arguments.length; i++){
        j = arguments[0].indexOf(arguments[i]);
        if(j > -1){
           arguments[0].splice(j, 1);
        }
    }
    return arguments[0];
}

you can call this function with no of args eg:

 filter([1,2,3,4,5,6,7,8,9], 1, 3, 5); //return [2,4,6,7,8,9]
 filter([1,2,3,4,5,6,7,8,9], 1); //return [2,3,4,5,6,7,8,9]

11 Comments

you not need in ...,arg1, arg2, arg3, arg4 and function filter(arr) is enough
Yes, #Grundy but this function should call with an array and arguments
but now it seems like max args count is 4
It not depend on no of args
i not say that it depends:-) i say - it seems like
|
-1

There are really good answers here, but you can do it very clean in this way, remember you have an objects option in filter method which you can use in the callback function, in this case i'm using it like : arguments[i] so I can check every value in the arguments array

function destroyer(arr) {

   for(var i = 1; i < arguments.length; i++){
     arr = arr.filter(isIn, arguments[i]);
   } 

   function isIn(element,index, array){
      if (element != this){
         return element;
      }
   }  
   return arr;
}

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.