Problem
If all elements in a javascript array are present in another array, I’m searching for a quick technique to remove them all.
// If I have this array:
var myArray = ['a', 'b', 'c', 'd', 'e', 'f', 'g'];
// and this one:
var toRemove = ['b', 'c', 'g'];
I’d like to perform the following operations on myArray to keep it in this state: [‘a’, ‘d’, ‘e’, ‘f’]
I use jQuery’s grep() and inArray() functions, which work well:
myArray = $.grep(myArray, function(value) {
return $.inArray(value, toRemove) < 0;
});
Is there a way to achieve this in pure javascript without looping and splicing?
Asked by Tap
Solution #1
Use the Array.filter() function to do the following:
myArray = myArray.filter( function( el ) {
return toRemove.indexOf( el ) < 0;
} );
As browser support for Array.includes() has grown, there has been a small improvement:
myArray = myArray.filter( function( el ) {
return !toRemove.includes( el );
} );
Next, using arrow functions, make the following changes:
myArray = myArray.filter( ( el ) => !toRemove.includes( el ) );
Answered by Sirko
Solution #2
The items of one array that aren’t in the other can be computed faster using ECMAScript 6 sets:
The time complexity of the entire technique is O(1), because the lookup complexity for the V8 engine browsers used these days is O(1) (n).
Answered by Benny Neugebauer
Solution #3
The following filter approach should suffice:
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;
});
This type of lookup technique can be inefficient if your toRemove array is large. It would be more efficient to generate a map with O(1) lookups rather than O(2) lookups (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]);
Answered by Ashwin Balamohan
Solution #4
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'}
];
myArray = myArray.filter(ar => !toRemove.find(rm => (rm.name === ar.name && ar.place === rm.place) ))
Answered by mojtaba roohi
Solution #5
If you’re working with a collection of things. Then the code below should work its magic, with an object property as the criterion for removing duplicate objects.
Duplicates have been deleted in the example below by comparing the names of each item.
Consider the following scenario. http://jsfiddle.net/deepak7641/zLj133rh/
Answered by Deepak Acharya
Post is based on https://stackoverflow.com/questions/19957348/remove-all-elements-contained-in-another-array