I am writing a function which takes as first argument an array (arr1), and then N number of arguments (arr2), by which it removes the N arguments (arr2) from the array (arr1). The function seems to be doing the job, except it stops immediately when the if statement becomes true. I know this because if I remove the if statement the loops are iterated till the end. Any ideas what I did wrong?
So below the returned array should be ['A','B','E'].
const removeFromArray = function(arr1, arr2) {
let arr_new = arr1;
first_loop:
for (const [y, elem] of arr1.entries()) {
for (let i=1; i<arguments.length; i++) {
if ((elem === arguments[i])) {
arr_new.splice(y);
}
}
}
return arr_new;
}
alert(removeFromArray(['A', 'B', 'C', 'D','E'],'C','D'));
splice modify original array so when you call it. It just removes all elements from y until the end of arr_new and arr_new refers to arr1.
const foo = [1, 2, 3, 4];
foo.splice(2);
console.log(foo); // [1, 2]
arr1.entries() is an iterator which continue to track arr1 internally so when you modify arr1 it would modify entries too, so this is why your loop is stopped - there are no elements after splice
To fix this problem, you can modify your code
if ((elem === arguments[i])) {
arr_new.splice(y, /*👉 remove only one element*/1);
}
⚠️ P.s. solution above still has problems with indexes because you modify the original array and relay on that index. This lead to incorrect overall result
This is proper solution of remove from array, without modification and with better complexity O(n)
const removeFromArray = function(arr1, ...arr2) {
const exclude = arr2.reduce((acc, curr) => {
acc.add(curr);
return acc;
}, new Set());
return arr1.filter((it) => {
return !exclude.has(it)
});
}
Here's an alternate take on what you're trying to accomplish. While arrow functions don't have arguments, you can still emulate it through rest parameters. Then you can just use a filter
const removeFromArray = (...args) => {
let arr1 = args[0], arr2 = args.slice(1)
return arr1.filter(a => arr2.indexOf(a) === -1)
}
console.log(removeFromArray(['A', 'B', 'C', 'D', 'E'], 'C', 'D'));