Seek and Destroy-Really Need to Understand Well

Seek and Destroy-Really Need to Understand Well
0.0 0

#1

Hello to all again,

In the seek and destroy challenge, I am stuck of why my code is not responding. As the challenge describes, it looks to “filter” the elements passed as arguments from a given array.

I added my code here with some comments of what I pretend the function to do in some steps, but honestly I’m all lost here of how the program/engine works.

Even though I read many times the concepts of argument objects and indexOf. I’m still not able to use it well in code.

This has been my resources

And of course

If someone could explain what I’m doing wrong here, what would be the next approach based of what I have in my code.

function destroyer(arr){
  //using filter method to return a new array out of the function
  var newArray = arr.filter(function(value){
    //defining argument objects
    var args = Array.from(arguments);
    
    //iterate through the arguments starting by index 1
    for(i=1; i < args.length; i++){
               // changing to strings for the numbers arguments
               //find the words using indexOf method
        return value.toString().indexOf(args[i]) >= 0;
    }
  });
  
  return newArray;
}

#2

Do you realize that args will be the arguments available to the filter function and not the arguments passed to the destroyer function?

Whenever you reference the arguments object, it refers to the arguments of the closest function. In this case, it will be the filter function. The filter function has 3 argument. In the example test case of:

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

the arguments object inside the filter function will look like:

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

You need to rethink you algorithm here. You do not need a for loop inside the filter function as whole purpose of the filter function is to iterate over the array preceding the call to it.

FYI - The replt you inserted into your original post has the following array:

var countries = ["Nicaragua", "USA", "Brazil", "Costa Rica", "Denmark", "Canada", "Mexico", "Bolivia", "Burundi", 101];

Even if you had the correct Free Code Camp solution for this challenge, it makes no sense to call destroyer([countries]), because the destroyer function (based on the challenge instructions) expects the first argument to be an array, followed by one or more arguments which represent the items to remove from the array. In your call of destroyer([countries]), you are not even specifying a valid array in the first argument. Also, you have no additional arguments for which you want to remove from the array passed in. To use the countries array, you would need to make the following example call:

destroyer(countries, "USA", "Denmark"); // return an array of countries without USA and Denmark.

#3

Hello Randell,

thanks a lot for replying. I’m still having difficulty of grasping the full concept and usability of argument objects as for much as I read and reread.

Let me start that I use repl.it as debugging, test and practice. That’s why my repl.it posted here was messy and unclear. One thing estranged in my code is when I want to return variable countries in the function, it returns an empty array, but if I use bracket [countries], it will return the countries array with double brackets [[…]]

If you see the disable code in the bottom for var newCountries, the one without the function, the code works well when I pass the arguments in the filter function and it also works the indexOf method when I pass specific argument in the indexOf(). I wanted to duplicate this small algorithm using it inside with function destroyer(arr){ }

Again I’m trying to figure out at what point I have to use the arguments object to pass multiple parameters when I verified the returned array.

Hopefully I’m making myself understand. Again I’m totally lost and disoriented on how to approach this.


#4

Ok Randell,

I decided to start this from scratch and follow this step by step if you could guide me here.

I have this new code:

var countries = ["USA", "Panama", "Costa Rica", "Brazil", "Chile", "Guyana", "Canada", "Mexico", "Argentina", "Venezuela"];

function destroyer(arr, str){
  var newCountries= arr.filter(function(value){
      return value.toLowerCase().indexOf(str.toLowerCase()) >= 0;
    
  });
  
  return newCountries;
}

destroyer(countries, "Chile");

if you see I have this new function that takes two parameters: one is the array and the other is the string we want to look for, but only two parameters.

In this code it returns the element if there is a match as new array and returns an empty array if there is not matching elements.

To have multiples parameters without specifying how many, because in the challenge we could find more than two elements, at what point here do I use arguments objects based on the logic of my new code.

Thanks a lot.


#5

See if the following function and comments helps you to understand:

var countries = ["USA", "Panama", "Costa Rica", "Brazil", "Chile", "Guyana", "Canada", "Mexico", "Argentina", "Venezuela"];

function destroyer(countriesArr, str){
  var args = Array.from(arguments); // creates an array of all the function arguments
  
  var findTheseCountries = args.slice(1); // gets all arguments after 1st argument we want to find
  
  var foundCountries= findTheseCountries.filter(function(country){
      return countriesArr.indexOf(country) >= 0;
      // captures country name passed into the function as an argument only if it is 
      // in the countries array which was also passed into the function
  });
  
  return foundCountries;
}

destroyer(countries, "Chile", "USA", "Russia");
// all arguments after first are the ones to find in countries array

#6

Thank you a lot. I think I am able to get it now thanks to your explanation in my second cleaner code.

The key for me was to use Array.from(arguments) which returns all the arguments into an array. By using console.log, the console showed the difference between function (arr) vs function (…arguments). With just using (arr), it only returns one argument whatever one it’s passed on, while (…arguments) will return all subsequent arguments after the first one. For example:

var countries = ["USA", "Panama", "Costa Rica", "Brazil", "Chile", "Guyana", "Canada", "Mexico", "Argentina", "Venezuela"];

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

destroyer(countries, "Ecuador", "Bolivia");//It will return only the full array of countries but the other arguments. 

On the other hand:

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

destroyer(countries, "Ecuador", "Bolivia");//Will return an array of length of 3 elements
                                                                 //Being index[0] the full countries array
                                                                //index[1] "Ecuador" and index[2] "Bolivia",
                                                               //plus any other subsequent arguments we want to add later

This is where my whole confusion was!!!

So after defining or converting the arguments object into a functional array with from() method, I would be able to select all tests arguments that start at index 1, so for this I select by using the splice method and defining a variable to it.

var testElements=Array.from(arguments).splice(1) 

This way if we console.log into the function will return all array elements starting at index 1.

function destroyer(arr){
  var testElements=Array.from(arguments).splice(1);
  console.log(testElements);
}

destroyer(countries, "Ecuador", "Bolivia"); //will return Ecuador, Bolivia, etc 

Having dominated this concept I could move on to the next step with it’s to iterate through the whole array using the filter method.

function destroyer(arr){
  var testElements=Array.from(arguments).splice(1);
 var newCountries=arr.filter(function(value){
  
  });
}

Like any other loop or iteration we want us to return something. In this case we want to return all those array elements that aren’t present with the ones we test by using the indexOf

function destroyer(arr){
  var testElements=Array.from(arguments).splice(1);
  var newCountries=arr.filter(function(value){
    return testElements.indexOf(value) === -1; //here it will return those elements that don't match the value parameter
                                                                      //A -1 means they were no match elements  
  });

  //Finally return the newCountries array
  return newCountries;
}

destroyer(countries, "Brazil", "Canada", "Mexico");//It will return ["USA", "Panama", "Costa Rica", "Chile", "Guyana", "Argentina", "Venezuela"] and so on 

This was very frustrating for me to understand, especially how arguments objects work and it really helped that I use console.log as debugging, something I’m not used to do.

Thank you a lot for your patience and reading all the way through my conclusions. Do you have any final comments to add? Do you know of any other challenges that uses argument objects?