The problem is that the arguments
keyword is usually bound to the current function, which in this case is the anonymous function used in filter
.
ES6 allows to fix this easily by introducing arrow functions, which don't bind arguments
.
(function destroyer(arr) {
var arg_num = arguments.length;
return arguments[0].filter(a => {
for (var i = 1; i < arg_num; i++){
if (a === arguments[i]) return false;
}
return true;
});
})([1, 2, 3, 1, 2, 3], 2, 3); // [1, 1]
However, note this function has cost n m
where n
is the number of elements in the array and m
is the number of additional arguments. But could be better.
For example, if the additional arguments will always be numbers, you can sort them, and then use dichotomic searches. This will cost n lg(m)
.
Another approach would be using a hash table. It will still cost n m
on the worst case, but only n
on average.
If you don't want to implement that manually, you can use a ES6 set. Its specific cost will be implementation dependent, but is required to be sublinear on average.
(function destroyer(arr, ...args) {
var s = new Set(args);
return arr.filter(a => !s.has(a));
})([1, 2, 3, 1, 2, 3], 2, 3); // [1, 1]