This problem is a bit tricky because you have to familiarize yourself with Arguments, as you will have to work with two or more but on the script you only see two. You will remove any number from the first argument that is the same as any of the other arguments.
The rest parameter syntax allows the function to accept an indefinite number of arguments, placed into an array. If you use the arguments object convert it into a regular array.
Hint 2
You may want to use various methods like: indexOf(), includes(), or filter(). When in doubt about any function, check the MDN docs!
Solutions
Solution 1 (Click to Show/Hide)
function destroyer(arr) {
const valsToRemove = Object.values(arguments).slice(1);
const filteredArray = [];
for (let i = 0; i < arr.length; i++) {
let removeElement = false;
for (let j = 0; j < valsToRemove.length; j++) {
if (arr[i] === valsToRemove[j]) {
removeElement = true;
}
}
if (!removeElement) {
filteredArray.push(arr[i]);
}
}
return filteredArray;
}
Code Explanation
Create an array of valsToRemove using Object.values(arguments).slice(1) and store it in the variable valsToRemove. We’ll use this to check against arr.
Start a basic for loop to iterate through arr. Nest another for loop inside the first, changing the integer variable j and arr to valsToRemove. This second loop will iterate through valsToRemove .
Within the second loop create an if statement, checking strictly === that the current value of arr[i] is equal to valsToRemove[j].
If the value at the current index is equal in both arrays, let removeElement to true remove it from arr.
If the value is not flagged for removal, add it the the filteredArray.
Outside of the nested loops, return the filteredArray.
Declare a variable named valsToRemove and set it equal to a new Array object from() the arguments passed into the function. Use the slice() method on the array of arguments, starting from the second index, 1.
Return the filtered array, using includes() in the callback function to check if val is not in valsToRemove; returning true to keep the value in the original array or false to remove it.
Why use var args = Array.prototype.slice.call(arguments) when var args = Array.from(arguments) does the same job in a seemingly more elegant and concise way?
Hi. I just finished this exercise and found out that my code is nowhere near the answer. However, it works. Can someone check if I did it right, and what points did I miss if ever? Here’s my code:
function destroyer(arr) {
arr = arguments[0];
var res= [];
for (var i = 1; i < arguments.length; i++) {
console.log(arguments[i]);
for (var j = 0; j < arr.length; j++) {
if (arr[j] === arguments[i]) {
delete arr[j];
console.log(arr);
}
}
}
for (var i = 0; i < arr.length; i++) {
console.log(arr[i]);
if (arr[i]) {
res.push(arr[i]);
}
}
return res;
}
destroyer([1, 2, 3, 1, 2, 3], 2, 3);
As you can see I didn’t use the filter method. However, I found out that I can actually do arr.filter(Boolean); to remove the null values inside the array. Can someone enlighten me about the Array.prototype.slice.call(arguments) and why I need to use is instead of setting my array to arguments[0]? Thank you.
I wanted to build upon my previous mutation solution, because this algorithm is about keeping the mutations, so I used my previous algorithm to find them, and used filter() to keep them:
function destroyer(arr) {
var targets = Array.prototype.slice.call(arguments, 1);
return arr.filter(function(val){
for(var i = 0; i < targets.length; i++){
if(targets.indexOf(val) < 0)
return true;
}
return false;
});
}
@gsuxlzt The spread operator which you are using is another way to achieve the similar result (Spread Operator), I instead use it to get an array with the targets to keep to compare against the main array.
You don’t need to assign arguments[0] to arr, arr is already arguments[0].Since there is only one named parameter in the function, it only references the first element of arguments.
The other arguments are put an array by using Array.prototype.slice.call(arguments).
the slice() method is used by an array to copy an array, but because arguments is not really an array(it’s an array-like object), you can’t do arguments.slice(1).So we use Array.prototype.slice.call(arguments, 1) to force arguments to use the slice method, as if it is an array.
I’ve just passed this task and found out that my solution is much simpler but it also works and I hope it could be useful for the understanding of basic algorithm of the method filter.
function destroyer(arr, val1, val2, val3) {
function filterForFalsy (arr) {
if (arr !== val1 && arr !== val2 && arr !=val3) {
I used a similar solution but realized that it will only work for up to 3 arguments. It passes all the tests on the exercise but the directions say 1 or more arguments so it should work for any number of arguments.
I did the same thing, couldn’t figure out how to create a callback function that would work with filter, still don’t really understand how the filter works.
function destroyer(arr) {
var args = arr.slice.call(arguments);
for (j=0; j<arr.length; j++){
for (i=1; i<arguments.length; i++){
if (arguments[i] === arr[j]){
delete arr[j];
}
}
}
return arr.filter(Boolean);
}
arr only returns the first argument because arr is the first argument. The other arguments 2, and 3, are not arr, they don’t have a parameter name because it was never set. Instead to access them you have to call them by arguments[1] and arguments[2].
function destroyer(arr) {
// Create two new arrays. One for the main array and another for unwanted chars.
var unwanted = [];
var givenArr = arguments[0];
// Push all other args to the unwanted array
for (var i = 1; i < arguments.length; i++) {
unwanted.push(arguments[i]);
}
// A function for testing if a member of the unwanted array matches a char of main array.
function tester (value) {
if (unwanted.includes(value)) {
return false;
} else {
return true;
}
}
// filter out chars which donot meet the above criteria
var filtered = givenArr.filter(tester);
// return the filtered array to the console.
return filtered;
}
destroyer([1, 2, 3, 1, 2, 3], 2, 3);
function destroyer(arr) {
// newArr comprises an array of all arguments passed in,
// slicing off the first
var newArr = Array.from(arguments).slice(1);
// fllter arr values against newArr values in line below
arr = arr.filter(function(val) {
// use ternary to return false if newArr val is in arr, else true
return (newArr.includes(val)) ? false : true;
});
// return updated arr
return arr;
}
destroyer([1, 2, 3, 1, 2, 3], 2, 3);