Seek & Destroy - need help understanding (arguments)

I’ve read the solutions to Seek & Destroy (https://forum.freecodecamp.com/t/algorithm-seek-and-destroy/16046).

In the intermediate solution, it uses this answer:

function destroyer(arr) {
  // Remove all the values
  var args = Array.from(arguments).slice(1);
  return arr.filter(function(val) {
    return !args.includes(val);
  });
}

destroyer([1, 2, 3, 1, 2, 3], 2, 3);

Specifically, I don’t understand this line at all Array.from(arguments).slice(1);

I understand that it’s trying to make ([1,2,3,1,2,3],2,3) into an array, but why does it use (arguments) instead of (arr)?

If anyone would be so kind to explain it clearly to me! Feeling baffled !

Try this:

console.log(Array.from(arguments)); // logs [ [ 1, 2, 3, 1, 2, 3 ], 2, 3 ]
  console.log(Array.from(arr)); // logs [ 1, 2, 3, 1, 2, 3 ] 

and so arguments.length = 3 (the array, 2, 3) but arr.length = 6 (1,2,3,1,2,3)

I think I understand (difference between arguments as everything that’s passed in the function and arr as one argument - like destroyer() only expects 1 argument) but I can’t explain it plainly…hope this helps though.

1 Like

took me a long time to understand it… had to read all about callbacks, but finally understand it now!

So arr only refers to [1,2,3,1,2,3] whilsts arguments are all the arguments passed into the destroyer function (in this case = [1,2,3,1,2,3], 2, 3)

My only question is… .is arguments some kind of global variable that is unique in javascript? I ask this because I realise it gets a different syntax highlighting

2 Likes

Actually MDN says the arguments object is a local variable, available within all functions. I don’t know if it’s specific to Javascript. (sorry, I don’t know any more than you do!)

2 Likes

Omg, I’ve done a crazy code… well, it works, but I think it’s not viable

function destroyer(arr) {
  
  for(var i = 1; i < arguments.length; i++){
    a = arguments[i];
    x = 0;
    for(var k = 0; k < arr.length; k++){
      if(arr[k] == a){
        x+= 1;
        if(x >= 1){
           delete arr[k];
        }
      }
    }
  }
  return arr.filter(Boolean);
  
}

destroyer([1, 2, 3, 1, 2, 3], 2, 3);
3 Likes

This was how I was going about it too. I was surprised to see they sliced the arguments.

I’m working on this challenge myself, and after reading about the Arguments object, I created this code to show the four basic methods you can use to convert the Arguments function object to an array:

function x() {
  var args1 = Array.from(arguments);
  var args2 = Array.prototype.slice.call(arguments);
  var args3 = [].slice.call(arguments);
  var args4 = [...arguments];
  var template = "The arguments object is not an Array. It is similar to an Array, but does not have any Array properties except length. For example, it does not have the pop method. However it can be converted to a real Array in many ways: \n method 1:  var args = Array.prototype.slice.call(arguments);  Result: {args1} \n method 2:  var args = [].slice.call(arguments);  Result: {args2} \n method 3:  var args = Array.from(arguments);  Result: {args3} \n method 4:  var args = [...arguments];  Result: {args4}";
  
  return template.replace("{args1}", args1).replace("{args2}", args2).replace("{args3}", args3).replace("{args4}", args4);
  
}

x(1,2,3,4);

copy/paste this into your console and you’ll see that all four methods create the same array.

2 Likes

You can remove the if clause if(x>=1) and delete arr[k] directly after if(arr[k]==a)…

function destroyer(arr) {

for(var i = 1; i < arguments.length; i++){
var a = arguments[i];

for(var k = 0; k < arr.length; k++){
  if(arr[k] == a){
    delete arr[k];
  }
}

}
return arr.filter(Boolean);

}

destroyer([1, 2, 3, 1, 2, 3], 2, 3);

I have a very basic solution to the “seek and destroy” challenge.
Have added comments in the code for better understanding. Please have a look.

function destroyer(arr) {
  // check the number of arguments  
  var numOfArg = arguments.length;
  
  // 'for loop' to compare each argument with the item inside the array
  for(i = 1; i < numOfArg; i++){
    
    // assign an argument to a variable
    var word = arguments[i];
    
    // callback function to pass in filter method;
    function checkIfEqual(val){
        // return the val which are not equal to the arguments
        return val !== word;
    }
    
    if(arr.indexOf(word) >= 0){
        arr = arr.filter(checkIfEqual);
    }
  }
  // return final arr
  return arr;
}

I have used the filter removeZero function, it is working here fine because 0 is considered a ‘falsy’ and so, all zeros are filtered out.
function destroyer(arr) {
x=[];
for(var i = 1; i < arguments.length; i++){
var a = arguments[i];

for(var k = 0; k < arr.length; k++){
if(arr[k] == a){
arr[k]=0;
}
}

}
function removeZero(value){
return value;
}
return arr.filter(removeZero);

}
destroyer([1, 2, 3, 1, 2, 3], 2, 3);

Hello drhectapus!

I struggled with this challenge for two days, and kept pushing myself to figure it out on my own. When I peeked and asked for a ‘Hint’ on this one, I remember seeing “Keep Reading those Docs!”, which meant keep pouring over javascript books I had checked out from the library as well as online resources.

Right when I was ready to wave the white flag and take a short cut, I convinced myself to try and translate “Seek and Destroy” into a game of war, and started using war terminology, which really helped me. . Here’s my war-game code that finally got me over the hump:

function destroyer(arr) {
// First Extract all the values from arr using the “arguments” object
// The first value of the argument [0] is the enemy, the target to be bombed
// All remaining values I named bombs—if any bombs hit the enemy
// that value would not be considered a “survivor”.
var enemy = arguments[0];
var bomb1 = arguments[1];
var bomb2 = arguments[2];
var bomb3 = arguments[3];
var survived = []; // values NOT destroyed by heat seeking bombs
// a blank array to take in survivors

// Next, get the length of the enemy, so we can loop through it
// If any of the enemy values are NOT bomb targets, they pass to the
// ‘survived’ array
for(i=0; i < enemy.length; i++)
if (enemy[i] != bomb1 && enemy[i] != bomb2 && enemy[i] != bomb3)
{
survived.push(enemy[i]);
}

return survived;
}
destroyer([1, 2, 3, 1, 2, 3], 2, 3);

Granted, this is not the most concise and efficient code, but it’s a solution, and more importantly, trying to find my own solution increased my knowledge a ton. Bravo freeCodeCamp! Great challenge

Hello, campers!
I started to do it with my old knowledge, doesn’t use filter or index of method. Can i succeede? Or this task has some limits? Because right now i have two red crosses and three green checks

  // Remove all the values
  for (var i = 0; i < arr.length; i++) {
    for (var j = 1; j < arguments.length; j++)
    if (arr[i] === arguments[j]) {
      arr.splice(i,1);
    }
   
  }
  
  return arr;
}

destroyer([2,3,2,3], 2, 3);

Here is my solution,

function destroyer(arr) {
  // Remove all the values
  var args = Array.prototype.slice.call(arguments, 1); // Args will be an array that pass to function, in this example, it return [2, 3]

  return arr.filter(x => args.indexOf(x) < 0); // Filter it, the same to previous challenge
}

destroyer([1, 2, 3, 1, 2, 3], 2, 3);
1 Like

I used a different method to solve this problem. I did add another argument to the function (I don’t know if this was allowed but it passed the test!). I think this is ES6 syntax, so I suppose that would also be another downside for compatibility. I spent some time trying to work out this problem and I had to look at hints 1 and 2.

function destroyer(arr, ...arg) {
  return arr.filter(item => !arg.includes(item));
}

i did that too !

I think receiving args is the key to this problem.