imnothardcore
imnothardcore

Reputation: 271

using .foreach to remove one array from another

I was attempting to use .forEach to remove the contents of one array(ignore) from another array(input).

As an example in the below I would expect the input array to contain "b" and "h" however it contains "g" and "h" when I run this.

curious why I am not getting my expected results and if this is a good method.

var input = ["a", "b", "g", "h"],                                               
    ignore = ["b", "h"];                                                        

var newInput = function(element, index, array){                                 
    if (input.indexOf(ignore[index]) > -1){                                     
       input.splice((ignore[index]), 1)                                        
    }                                                                           
}                                                                               

  ignore.forEach(newInput);

Upvotes: 0

Views: 70

Answers (4)

Jaromanda X
Jaromanda X

Reputation: 1

var input = ["a", "b", "g", "h"],
    ignore = ["b", "h"];                        

var newInput = function(element, index, array){
    if (input.indexOf(ignore[index]) > -1) {
       input.splice(input.indexOf(ignore[index]), 1)
//                  ^^^^^^^^^^^^^  added this
    }
} 

ignore.forEach(newInput);

but that code could be cleaner, e.g. ignore[index] is element

var input = ["a", "b", "g", "h"],
    ignore = ["b", "h"];

var newInput = function(element) {
    var index = input.indexOf(element);
    if (index > -1){
       input.splice(index, 1)
    }
}

ignore.forEach(newInput);

If you really want to impress the girls

var input = ["a", "b", "g", "h"],
    ignore = ["b", "h"];

var newInput = function(element, index) {
    ~(index = input.indexOf(element)) && input.splice(index, 1);
}

ignore.forEach(newInput);

I'll let you figure out that one liner :p

mutliple deletions

var newInput = function(element) {
    var index;
    while (~(index = input.indexOf(element)))
        input.splice(index, 1);
}

ignore.forEach(newInput);

Upvotes: 1

user663031
user663031

Reputation:

Array#filter is probably the best approach, but if you want to remove the ignored elements in-place, as I infer from your use of splice, you can do:

function ignore_elements(input, ignore) {
  var i = 0;
  while (i < input.length)
    if (ignore.indexOf(input[i]) !== -1) input.splice(i, 1);
    else i++;
}

By looping over the elements in the input, instead of ignore, you can more easily eliminate all occurrences of the elements to be ignored, not just the first one.

Upvotes: 1

bentinata
bentinata

Reputation: 334

Replace your conditionals with input.indexOf(element) > -1.

Since you are forEach-ing the ignore array, ignore[index] is the same as element.

And change splice to splice(input.indexOf(element), 1).

Array.splice() takes index as first arguments, and you are using the element instead.

Upvotes: 1

Mauricio Poppe
Mauricio Poppe

Reputation: 4876

You should use Array.prototype.filter instead

var input = ['a', 'b', 'g', 'h']
var ignore = ['b', 'h']
var newInput = input.filter(function (el) {
  return ignore.indexOf(el) === -1
})

Note that input remains unchanged

Upvotes: 1

Related Questions