Javascript arrays: remove all elements contained in another array

Javascript arrays: remove all elements contained in another array

I am looking for an efficient way to remove all elements from a javascript array if they are present in another array.
// If I have this array:
var myArray = [‘a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘f’, ‘g’];

// and this one:
var toRemove = [‘b’, ‘c’, ‘g’];

I want to operate on myArray to leave it in this state: [‘a’, ‘d’, ‘e’, ‘f’]
With jQuery, I’m using grep() and inArray(), which works well:
myArray = $.grep(myArray, function(value) {
return $.inArray(value, toRemove) < 0; }); Is there a pure javascript way to do this without looping and splicing?

Solutions/Answers:

Solution 1:

Use the Array.filter() method:

myArray = myArray.filter( function( el ) {
  return toRemove.indexOf( el ) < 0;
} );

Small improvement, as browser support for Array.includes() has increased:

myArray = myArray.filter( function( el ) {
  return !toRemove.includes( el );
} );

Next adaption using arrow functions:

myArray = myArray.filter( ( el ) => !toRemove.includes( el ) );

Solution 2:

The filter method should do the trick:

const myArray = ['a', 'b', 'c', 'd', 'e', 'f', 'g'];
const toRemove = ['b', 'c', 'g'];

// ES5 syntax
const filteredArray = myArray.filter(function(x) { 
  return toRemove.indexOf(x) < 0;
});

If your toRemove array is large, this sort of lookup pattern can be inefficient. It would be more performant to create a map so that lookups are O(1) rather than O(n).

const toRemoveMap = toRemove.reduce(
  function(memo, item) {
    memo[item] = memo[item] || true;
    return memo;
  },
  {} // initialize an empty object
);

const filteredArray = myArray.filter(function (x) {
  return toRemoveMap[x];
});

// or, if you want to use ES6-style arrow syntax:
const toRemoveMap = toRemove.reduce((memo, item) => ({
  ...memo,
  [item]: true
}), {});

const filteredArray = myArray.filter(x => toRemoveMap[x]);

Solution 3:

If you are using an array of objects. Then the below code should do the magic, where an object property will be the criteria to remove duplicate items.

Related:  How to add jQuery in JS file

In the below example, duplicates have been removed comparing name of each item.

Try this example. http://jsfiddle.net/deepak7641/zLj133rh/

var myArray = [
  {name: 'deepak', place: 'bangalore'}, 
  {name: 'chirag', place: 'bangalore'}, 
  {name: 'alok', place: 'berhampur'}, 
  {name: 'chandan', place: 'mumbai'}
];
var toRemove = [
  {name: 'deepak', place: 'bangalore'},
  {name: 'alok', place: 'berhampur'}
];

for( var i=myArray.length - 1; i>=0; i--){
 	for( var j=0; j<toRemove.length; j++){
 	    if(myArray[i] && (myArray[i].name === toRemove[j].name)){
    		myArray.splice(i, 1);
    	}
    }
}

alert(JSON.stringify(myArray));

Solution 4:

Lodash has an utility function for this as well:
https://lodash.com/docs#difference

Solution 5:

ECMAScript 6 sets can be used for computing the different elements of two arrays:

const myArray = new Set(['a', 'b', 'c', 'd', 'e', 'f', 'g']);
const toRemove = new Set(['b', 'c', 'g']);

const difference = new Set([...myArray].filter((x) => !toRemove.has(x)));

console.log(Array.from(difference)); // ["a", "d", "e", "f"]

Solution 6:

I just implemented as:

Array.prototype.exclude = function(list){
        return this.filter(function(el){return list.indexOf(el)<0;})
}

Use as:

myArray.exclude(toRemove);