简体   繁体   中英

JavaScript Remove Multiple Values from Array Using Filter and Loop

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.

Eg

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 (ie 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);
}

Your filterer function can be much simpler:

function filterer (value) {
    return itemToRemove.indexOf(value) === -1;
}

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.

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 .

The following code will remove elements from an array. The elements it removes are defined by any extra parameters. ...remove is an ES6 feature that aggregates extra parameters into a single array.

I will iterate over the ...remove array and delete that element from the main array we are working on.

Here is a JSFiddle: https://jsfiddle.net/zzyopnnp/

...extra_parameters is not supported in most browsers, you may want to use the arguments object.

function removeIndex(array, index) {if(index>-1){array.splice(index, 1);}}

function destroyer(array, ...remove) {
    remove.forEach(function(elem, index) {
        removeIndex(array, index);
    });
};

var arr = ["tree", "hamburger", 53];
destroyer(arr, "tree", 53);
console.log(arr);

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--
    }
}

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]

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM