Bonfire: Seek and Destroy Solution

Two more Bonfires (unless Free Code Camp wants to add more) after Seek and Destroy! I’m a little excited to be finished with these so we can move onto some more complicated challenges. Nothing so far about these Bonfires has been particularly challenging and they’ve been a great reminder as to what Javascript can accomplish–on a more development-focused scale. So let’s see what we can do about Seek and Destroy. Here’s what the Bonfire gives us:

function destroyer(arr) {
  // Remove all the values
  return arr;
}

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

We need to remove the arguments from the array provided to the destroyer() function. We can see in the arguments that it probably wants us to remove all 2s and all 3s. If we’ve already survived the previous Bonfires, then this one will be pretty easy.

Approaching the Problem

  1. I know that I need to remove all 2s and 3s from the array, but I can pretty much guarantee that the Bonfire won’t just be filtering out static 2s and static 3s. It’s going to change things up on us, and the best way for us to come up with a surefire way to get everything is to turn the two arguments into an array themselves.
  2. Remember when we talked about indexOf() in the Mutations Bonfire? We’ll be using it again here to help us identify where in the array of numbers we need to be in order to remove those values.
  3. Finally, I’m going to need to use filter() to remove the argument values from the array in order to validate my Bonfire.

All right, we have our game plan, so let’s get started.

Changing Arguments Into an Array

The first thing I’m going to approach is the easiest and, incidentally, the first thing on my to do list. I always like to start off with the easiest thing because it’s less intimidating than trying to tackle the hardest task first. So, what I’m going to do is turn the two arguments into an array. We’ve done something like this in the past, only we were using strings then. This is going to be an array of numbers now, so here’s what I’m doing:

function destroyer(arr) {
var myArguments = [];
for (var i = 1; i < arguments.length; i++) {
myArguments.push(arguments[i]);
}

  return arr;
}

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

What I’ve done up there is create an empty array called myArguments. That array will take the arguments from the destroyer() function so that we can use whatever values Bonfire throws at us. The catch is, we don’t know what those arguments are going to be. So we use the arguments object to identify those values and push them to our myArguments array. Looks like we’re going to have to take a brief detour.

The Arguments Object

The arguments object exists in Javascript to present the arguments that are passed into a function. This is useful for our purposes because it retrieves whatever we input as the index number. For example, let’s take our destroyer() function from this bonfire. If you were to return arguments[1], you would receive the number 2 as a result. Go ahead:

function destroyer(arr) {
return arguments[1];
}

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

Let’s try something that’s a little easier to visualize. Here’s another function, this time there are strings instead of numbers so we know for sure what arguments is useful for:

function cats(arr) {
return arguments[2];
}

cats("Bengal", "Scottish Fold",["Persian", "Russian Blue", "Moggy"], "Abyssinian");

Plug that into a console and it will return the array. You can go ahead and play with arguments a bit more by changing the number, but whatever the number you plug in will correspond to the arguments fed into the cats() function. One of the caveats of the arguments object is that it exists only within a function. So you can’t use it all willy-nilly outside or you’ll encounter an error.

Now, my next move in this Seek and Destroy solution is to use filter() and if I’m remember things correctly, we haven’t encountered that method yet. So let’s dive in.

The Filter() Method

Filter() is a Javascript method that creates a new array based upon a function that was fed to it. That function must return a value in order for filter() to create an array. This is a particularly useful method because we’re essentially going to use it to test for the values inside our new myArguments array, and if those values happen to exist in myArguments, they will fail the filter() test and not be included in the array we’re going to build. Filter() looks for a true or a false value. True gets added to the array, false does not. Here’s an example of filter() in action:

function isLess(number) {
 return number <= 10;
 }

var filtered = [4, 87, 11, 9, 19, 789].filter(isLess);
 console.log(filtered);

The console log on that one should be 4, 9. What’s happening up there is filter is taking in a function. The function is called isLess and is defined with an argument of number. Number returns whatever is less than or equal to 10. Which in our array is just two of the six numbers: 4 and 9.

Now that we know what filter() is expecting, let’s go solve this Seek and Destroy challenge.

Seek and Destroy Solution

Knowing that I can use the arguments object to my advantage, I now have two arrays. One that I’m given by the Bonfire to filter numbers out of. Another one that holds all the two (or more) arguments that I want to filter out. All we need to do now is write the filtering code and return arr.

function destroyer(arr) {
// Create an array of arguments using the arguments object
var myArguments = [];
for (var i = 1; i < arguments.length; i++) {
myArguments.push(arguments[i]);
}
// Return arr after filtering values in myArguments
return arr.filter( function(remove) {
  return myArguments.indexOf(remove) < 0;
});
 }

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

We’re seeing a return of our old friend, indexOf() in the above solution. Let’s walk through this Seek and Destroy solution from top to bottom now. destroyer() the function has three arguments. The first is an array, the next two are numbers. Our challenge was to filter out the two arguments from the provided array in destoyer().

What we do first is create an array callled myArguments. myArguments uses the arguments object to iterate through all the arguments provided in destroyer. The for loop starts at 1, which is the second value in the array (2). You may have noticed we don’t start at 0 like usual because we don’t want our for loop to populate the array itself into our new myArguments array. Once the for loop finishes, myArguments should contain all the arguments the Bonfire wants us to use in order to exclude from the array.

After we have our myArguments array set up, we must return arr with the excluded values. What we do is use the filter() method. Filter() takes in a function that is used to exclude whatever values myArguments is holding. Inside of our filter() method, we have a function that takes in another argument called remove. In the function itself, remove identifies each value of myArguments using indexOf() and returns them to remove for filter() to use.

Remove sends the values we evaluated up the chain and back to the filter() method, which determines that all values remove returned must be filtered out of arr. Then we return arr with a new array, devoid of the values inside of myArguments. Plug that into the Bonfire and it will evaluate.

Resources

MDN, Filter()
Describes the filter() method and shows some examples of its usage.

MDN, Arguments Object
Explains the arguments object and how it works. Very quick and easy read.


Posted

in

by

Comments

16 responses to “Bonfire: Seek and Destroy Solution”

  1. gabriel

    goodwork; but i dont get something while did u use less than <0 after indexof

  2. KIm Hughes

    Kudos and thanks for your detailed and clear explanations. Very insightful.

  3. D’Oh!

    Thank you, thank you, THANK YOU!

    I’ve been dropping by for the last couple of days since I found your site, and it’s given me a much better and clearer understanding than any of the countless reference sites out there. You have an excellent way of explaining these exercisees, breaking them down, and working through to a solution. I don’t feel like pulling my hair out over these challenges anymore, and can tackle them without feeling lost half the time. Can’t thank you enough.

    1. I’m always really happy to hear any of these Javascript write-ups were able to help anyone understand and learn the language. Thank you for dropping by and leaving a comment, D’Oh! 🙂

  4. yes, very helpful, thanks a ton for your wonderful write-ups!

    1. My pleasure, blast0id. Thanks for leaving a comment. 🙂

  5. paolo

    I’m beginning to understand now except for the “remove” function inside the filter, how do you define remove is it another function?

    1. Hi Paolo! Thanks for dropping by and leaving a comment. “Remove” is the argument name for the function. I named it remove, but it could technically be named anything because it’s just an argument (it’s not a function, keyword or anything special). For example, here’s the solution again with “remove” renamed to “extract” and that would still work just like it did in the post:

      function destroyer(arr) {
      // Create an array of arguments using the arguments object
      var myArguments = [];
      for (var i = 1; i < arguments.length; i++) { myArguments.push(arguments[i]); } // Return arr after filtering values in myArguments return arr.filter( function(extract) { return myArguments.indexOf(extract) < 0; }); } destroyer([1, 2, 3, 1, 2, 3], 2, 3);

      I hope that helps clear things up a bit!

      1. Kebenaran

        I still don’t understand the use of function (extract) and the <0 part;
        I thought myArguments already contains the array that we need (by applying the .push function.

        Can somebody please try a simpler way to breaking down this line please

        function(extract) { return myArguments.indexOf(extract) < 0;

        I would really appreciate it.

        Thanks.

        1. Hi Kebenaran, let me try it again:

          With this function below, we are trying to get a list of numbers to remove from the array:

          function(extract) { return myArguments.indexOf(extract) < 0; We create a function with an argument that I called "extract" up there. Within the function, we then want to return whatever myArguments' numbers are back to filter() where it is used to remove the numbers identified. If anyone else can provide a clearer response or an alternative approach, I'd really appreciate it. 🙂 There's also these approaches which might help, they're different but much less verbose: https://forum.freecodecamp.com/t/algorithm-seek-and-destroy/16046

  6. Nkem

    Sigh, where do I begin? You are a life saver and a genie. You make these Bonfires look so easy, thank you so much and keep helping newbies like myself understand JavaScript.

    PS: This line of code “return myArguments.indexOf(remove) < 0;", why less than 0?

    1. Hi Nkem, thanks for dropping by and leaving a comment. Hopefully you’re still checking this and I didn’t take too long to get back to you. The less than 0 value exists to ensure that our filter runs through all the values in the array we’re filtering and either returns a true or a false when it checks.

    2. When you DON’T find a value, indexOf() it returns -1. As you remember, it is asked to retain only the values that ARE NOT in arguments that follow from the test array.

      1. Thanks for dropping by and leaving a clarification, Mihnea. 🙂

  7. Vik

    I should give you a lot of credit for posting these Bonfires….its not easy to do any of these Bonfires from FCC.
    For someone who just started learning JS or any other programming languages, these explanations help.
    Keep Coding Keep Up the Good Work!!

    1. Thanks so much for dropping by and leaving a comment, Vik. I’m so glad these write ups have been helpful for so many people learning JS. 🙂