Seek and Destroy - Basic Alogorithm Scripting - Help

My solution

`function destroyer(arr) {

var args = arguments;
for(var i=1; i<args.length; i++) {     
 arr = arr.filter(function(val){
   return val !== args[i];
 });
 }  

return arr;
}

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

loved it, you can add a ā€œ;ā€ after your for loop to get rid of the warning.

This one almost drove me insane :dizzy_face:

First, I tried using .indexOf like @tddaniel114, but apparently I wasnā€™t casting the arguments to an array correctly because I kept getting blank.indexOf is not a function errors.

Second, I tried using a loop like a bunch of people here, but I couldnā€™t seem to get that right either.

(Iā€™d share my code from these attempts, but I didnā€™t think to save them at the time.)

So I finally just hard coded it to pass the test:

  function destroyer(arr) {
  
  var arr1 = Array.from(arr);
  
  var newArray = Array.prototype.slice.call(arguments,1);
  
  var result = arr1.filter(function(value){

   return value !== newArray[0] && value !== newArray[1] && value !== newArray[2];
  });
  
  return result;
}`

I know this is bad practice, and I am going to go back and figure out how to do it better, but for now Iā€™ve moved on to preserve my motivation to learn.

It doesnā€™t seems necessary to me to shift the args array because the filter condition works the same if arg[0] is an array instead of a number.

function destroyer(arr) {
  var args = Array.from(arguments);
  
  return args[0].filter(function(item) {
      return !args.includes(item);
  });
}
2 Likes

Hey P1xt, I try to understand your code below cuz I like your approach to solve problems : [quote=ā€œP1xt, post:19, topic:4477ā€]
function destroyer(arr) {
var args = Array.prototype.slice.call(arguments);
var inputArray = args.shift();

return inputArray.filter(function(x) {
return args.indexOf(x) === -1;
});
}

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

Could you explain me this : I know that we want to return the inputArray with a filter but the function only check ā€œxā€ if its found in the args arrayā€¦ but what is ā€œxā€ ? and I dont see anything that we remove from inputArrayā€¦ I really try to get into it !

     return inputArray.filter(function(x) {
     return args.indexOf(x) === -1;

Thank you very much for your detailed explanation ! Thats really helpful. :slight_smile:

Regarding again the code i have a stupid question :

var args = Array.prototype.slice.call(arguments);
var inputArray = args.shift(); 

console.log(args) = [2,3]
soā€¦
console log(inputArray) = inputArray = args.shift() = [2,3].shift => should be [2] the first elementā€¦its the shift methodā€¦ why it goes back to the ā€œarrā€ when here its ā€œargsā€ its called

True it was the console.log(args) after the shifting which will confused me :slight_smile:

@PortableStick is it ok to mix higher order functions like .filter with a bog standard for loop? I tried using the same logic except I tried to use .map instead of the for loop but I couldnā€™t implement it correctly. I tried like this, and a few other iterations but I get the error message: Cannot read property ā€˜filterā€™ of undefinedā€¦telling me that newArray is undefined!!
function destroyer(arr) { var newArray=arr; var args = Array.prototype.slice.call(arguments,1); var newArgs = args.map(function(index){ var newArray=newArray.filter(function(val){ return val!== index}) }) console.log(newArray) }

thoughts ?

The key issue with your code example is this line

var newArray=newArray.filter()

When you use the var keyword, youā€™re redeclaring the variable in a new scope. I can assume you want the newArray at the top of destroyer(), but by declaring it the way you did in the filter callback, youā€™ve made that impossible. newArray.filter canā€™t be read because it is, in fact, undefined. Try something like

var tmpArray=newArray.filter()

It is possible to nest higher order functions. Just like nesting any loop, though, itā€™s a surefire way to degrade performance, so be judicious with it.

1 Like

@PortableStick thanks ill give it a try and see if I can get it to work.

###Thanks @xarimus, it helped me solve the challenge.

As campers have shown their code I throw in one more: my take was purely functional which (in my mind) makes very clean and readable code:

function destroyer(arr) {
  return arr.filter(x => Array.prototype.slice.call(arguments, 1).indexOf(x) == -1);
}

Here we convert arguments to an array and filter elements of arr which are not in it (hence index -1). It will be more efficient to assign an variable for converted array of arguments if thereā€™s long lists to filter (either arr of arguments) as now the conversion is done again for each element of arr.

I think the whole idea of this excercise is to understand how one can use functional methods and decrease the amount of code . Thatā€™s way there is these tips to look for :slight_smile: