Reputation: 99
Let's say I have an array such as: [1, 1, 2, 2, 3, 3, 4, 5]
And I want to remove this array of elements [1, 2, 3, 4, 5]
So in the end I want to be left with [1, 2, 3]
I have tried using the method below but it removes all copies of the elements from the main array.
myArray = myArray.filter( function( el ) {
return !toRemove.includes( el );
} );
Upvotes: 1
Views: 1492
Reputation: 13964
Here is a way to do it using filter
, indexOf
and splice
.
const input = [1, 1, 2, 2, 3, 3, 4, 5];
function removeSubset(arr, subset) {
const exclude = [...subset];
return arr.filter(x => {
const idx = exclude.indexOf(x);
if (idx >= 0) {
exclude.splice(idx, 1);
return false;
}
return true;
});
}
console.log(removeSubset(input, [1, 2, 3, 4, 5]));
Upvotes: 2
Reputation: 37755
You can use Filter and Shitf and Sort
let arr = [1, 1, 2, 2, 3, 3, 4, 5]
let remove = [1, 3, 2, 4, 5].sort((a,b)=>a-b)
let op = arr.sort((a,b)=>a-b).filter(e => ( remove.includes(e) ? (remove.shift(), false) : true ))
console.log(op)
Upvotes: 1
Reputation: 17190
One solution is looping on the array of elements to remove and for each one remove the first element found on the input array:
const input = [1, 1, 2, 2, 3, 3, 4, 5];
const removeItems = (input, items) =>
{
// Make a copy, to not mutate the input.
let clonedInput = input.slice();
// Search and remove items.
items.forEach(x =>
{
let i = clonedInput.findIndex(y => y === x);
if (i >= 0) clonedInput.splice(i, 1);
});
return clonedInput;
}
console.log(removeItems(input, [1,2,3,4,5]));
console.log(removeItems(input, [1,2]));
console.log(removeItems(input, [1,99,44,5]));
If you still want to use filter, you can use the items to remove as the this
argument of the filter, something like this:
const input = [1, 1, 2, 2, 3, 3, 4, 5];
const removeItems = (input, items) =>
{
return input.filter(function(x)
{
let i = this.findIndex(y => y === x);
return i >= 0 ? (this.splice(i, 1), false) : true;
}, items.slice());
}
console.log(removeItems(input, [1,2,3,4,5]));
console.log(removeItems(input, [1,2]));
console.log(removeItems(input, [1,99,44,5]));
Upvotes: 1
Reputation: 386520
You could get a Map
and count the values and filter by checking the count and decrement the count if found.
var array = [1, 1, 2, 2, 3, 3, 4, 5],
remove = [1, 2, 3, 4, 5],
map = remove.reduce((m, v) => m.set(v, (m.get(v) || 0) + 1), new Map),
result = array.filter(v => !map.get(v) || !map.set(v, map.get(v) - 1));
console.log(result);
Upvotes: 1