Not sure what to do with seek and destroy

Not understanding where to go from here.

I also saw the hint says to use let args = Array.prototype.slice.call(arguments); the call method based on my understanding is used for a this method, which is not included here. (I have read the mozilla doc with a similar example but I don’t understand)

  **Your code so far**

function destroyer(arr) {
let args = Array.prototype.slice.call(arguments);

return arr
  .filter(arr => arr.includes(args[1]));
}

console.log(destroyer([1, 2, 3, 1, 2, 3], 2, 3));
  **Your browser information:**

User Agent is: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.182 Safari/537.36.

Challenge: Seek and Destroy

Link to the challenge:

1 Like
console.log(args)

See what this is giving you, think about how you could use it and proceed.

I did that but I’m not sure what to do

I’d again ignore the hints or the idea of doing anything fancy.

What do you see when you run


function destroyer(arr) {
  console.log(arguments);
}

console.log(destroyer([1, 2, 3, 1, 2, 3], 2, 3));

Hmm I see { '0': [ 1, 2, 3, 1, 2, 3 ], '1': 2, '2': 3 } which I’m clueless on.

Btw I tried this approach but actually realized I don’t understand why this should return [1, 1]. Isn’t it asking to remove (and assuming return) elements from the initial array that include other elements in the following array?

let result = [];
   let args = Array.prototype.slice.call(arguments);
   for (let i = 1; i < args.length; i++) {
     if (args[0].includes(args[i])) {
       result.push(args[i]);
     } 
   }
   return result; 
}

The title is literally “seek and destroy” not “seek and return” :wink:
You are supposed to REMOVE every occurence of these elements. So you need to either find a command that removes elements from an array or create a new array and fill it according to those conditions.

Right, so with the arguments object, you get every argument passed into the function. The first argument is the starting array. Every other argument is a value that you need to strip out of the starting array.

You know me, I start my code on pencil and paper. So I’d ask myself

  1. How do I start with a list of numbers and cross out every number that is also on a second list of numbers that are not permitted, by hand.
  2. How can I write that logic with basic loops and if statements.
  3. How can I refactor that logic to use pretty higher order language features.

That is the arguments object. Formatting it to a little more readable form:

{
  '0': [ 1, 2, 3, 1, 2, 3 ], 
  '1': 2, 
  '2': 3
}

Those are the things that were passed into the function as arguments.


This:

let args = Array.prototype.slice.call(arguments);

is a (rather oldfashioned) way to turn that arguments object into an array. So args is now this:

[
  [ 1, 2, 3, 1, 2, 3 ], 
  2, 
  3
]

Once you’ve sorted out how you want to solve this (Jeremy already made suggestions), you can think about which parts of the arguments you need where, and how you want to access them.

1 Like

One of my least favorite things about these ‘hints’ in the guide post articles is that they rapidly become outdated.

I guess those old guide posts will all be gone when the new curriculum is up? Ideally, with a new curriculum, it would also come with solutions written by experienced people, gradually advancing from “only with for loops and if statements” to “check out this fancy one-liner”.

My understanding is that a lot of those guide post solutions are actually user submitted. We try update the rough edges as they come to our attention, though feel free to make a #contributors post if you have improvement suggestions for any particular article.

I don’t understand how this Array.prototype.slice.call(arguments); works (I get what you guys are saying it does, but I don’t understand how), but what I would do is check each item in the first array and see if it matched 2nd array, 3rd etc. Then write the ones that don’t match.

I guess my loop wasn’t going to the right direction? I tried adding ! in front of args[0] to return only those that don’t include the other arrays but it’s not working

Also tried splice

function destroyer(arr) {
  let args = Array.prototype.slice.call(arguments);
  for (let i = 0; i < args.length; i++) {
     // if the first array includes upcoming arrays
     if (args[0].includes(args[i])) {
     // remove 1 element at index of args[i]
       args.splice(indexOf(args[i]),1);
    }
  }
  return result.push(args); 
}

I’m just trying not to look at any solutions to get this, so I’m sorry but I’ll probably keep posting a lot questions for the remainder of the curriculum. I wish I didn’t need to…

It’s fiddly to modify an array as you iterate over it. When you splice out an entry at location i, then the entry at location i+1 moves down to location i. You have to either account for this, or adjust your approach to avoid this.

I can use slice, that won’t modify the array correct? But I’m not getting the answer if so btw.

**update I looked at the solutions and this video since being stuck no this all day, but I’d rather figure out how to fix this using my approach. I don’t feel theres been enough practice creating Array.prototype.slice.call(arguments); or let valsToRemove = Object.values(arguments).slice(1); so I’m not sure what’s going on with either solution mine or theirs. Can someone explain this to me, I still don’t understand these type of functions and carefully reviewing the last section on functions didn’t help. If it’s not important and I should ignore the freecodecamp solutions then let me know thanks

If you make a change and have questions about your modified code, we’ll need to see the modified code.

I don’t have questions about the code from that video since it’s explained, but I was just unable to get to that on my own. Was there a way to fix my last code attempt in this thread?

Sure, it can be repaired. What have you tried to address the splice issue?

Dunno the english word, maybe “desk-test”? “Paper-test”?
If you got a short code, grab a piece of paper and try to execute the code yourself - think about what the thing you just wrote is actually doing.

For example, you start with i=0 → so what is args[i] in that case?
Secondly, you got an “if” in your for-loop. That thing is executed at most once per loop. How often will you for-loop actually loop? How often will the if-statement be executed at most? You’ll notice those numbers alone are not enough to solve the example problem.

1 Like

It’s your job to practice these things, you see there’s no way around it, because the challenges could explain this with words - but it wouldn’t click and it wouldn’t stick and it wouldn’t sink in. Same with array methods .map, .filter and .reduce. I can explain what they do, but you won’t fully understand it unless you use those methods yourself many times. You do practice a lot, so just keep going, eventually it will make sense.

Nevertheless, I’ll try to walk you through what this does:

let args = Array.prototype.slice.call(arguments);

The purpose is to transform the arguments object into an array.

.slice is a method that is available for arrays, and it returns a new array (what we want, we want to get an array with the arguments as items in the end, right now we have an object with the arguments as items).

Because .slice is an array method, we can’t use it on anything that’s not an array. This would cause an error:

let args = arguments.slice()
// Uncaught TypeError: arguments.slice is not a function

JavaScript looks at the arguments object, and we tell it to use an array method on it, which it can’t. It’s like this:

let myLunch = motorcycle.cook()
// Type Error
let myLunch = pasta.cook()
// Fine

Now for the .call method. You can use it to tell JavaScript what the this keyword should point at.

let args =   Array.prototype.slice     .call(arguments);

                   /\                         /\
                   ||                         ||
       |  get me the slice method  |   and call that method 
       |  from the array prototype |   with "arguments" being "this"

Or with my above example:

let myLunch =   Food.prototype.cook   .call(motorcycle)

Yes JavaScript, I WANT cooked motorcycle for lunch. I know you can’t cook motorcycles, but I’ll tell you how to do it. You’ll take the .cook method from the Food prototype, and use it with this being my motorcycle instead of pasta or potato.

Well I hope that made some sense. I don’t think it will at this point, but doesn’t matter. It’s not that important for this challenge.

1 Like