Seek and Destroy flyin

Tell us what’s happening:
Just wondering if anyone can help me understand why this doesn’t push the values to the array ‘c’.

Thank you,

Your code so far


function destroyer(arr) {
  let a = Array.from(arguments);
  let b = a[0];
  a.splice(0,1);
  let c = [];
  a.forEach((x) => b.indexOf(x) < 0 ? c.push(x):'');
  console.log(c);
  return c;
}

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

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:59.0) Gecko/20100101 Firefox/59.0.

Link to the challenge:
https://learn.freecodecamp.org/javascript-algorithms-and-data-structures/intermediate-algorithm-scripting/seek-and-destroy

@camperextraordinaire I had the array comparison backward. Also, thank you for the advice! I rewrote the function below. Does this seem like an appropriate solution? I don’t just want to just pass the challenges but have a clearer understanding in writing good, efficient, and effective code as well.

Thank you!

function destroyer(arr) {
  let a = Array.from(arguments);
  let b = a[0];
  a.splice(0,1);
  let c = [];
  b.forEach(function(x) { 
    if (a.indexOf(x) < 0) {
      c.push(x);
    }
  });
  console.log(c);
  return c;
}

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

@camperextraordinaire That took me a bit to understand but that works really well. This is how I modified the declaration and it allows me to completely delete the 3 lines. Thank you for your very instructive comments!!

function destroyer(b, ...a) { 

@camperextraordinaire So something more like this for a final solution?

function destroyer(arr, ...args) {
  let c = [];
  arr.forEach(function(x) { 
    if (args.indexOf(x) < 0) {
      c.push(x);
    }
  });
  console.log(c);
  return c;
}

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

@camperextraordinaire I guess the best description is a cleaned array

function destroyer(arr, ...args) {
  let clean = [];
  arr.forEach(function(x) { 
    if (args.indexOf(x) < 0) {
      clean.push(x);
    }
  });
  return clean;
}
1 Like

@camperextraordinaire This is what I came up with using the filter() function. It seems like this could still be more concise.

function destroyer(arr, ...args) {
  let filtered = arr.filter(function(element) {
    return args.indexOf(element) === -1;
  });
  return filtered;
}

@camperextraordinaire I like this solution. I’ll look at includes method also.

function destroyer(arr, ...args) {
  return arr.filter((element) => args.indexOf(element) < 0);
}

@camperextraordinaire Is it most appropriate to use let versus const or var?

let destroyer = (arr, ...args) => arr.filter((element) => args.indexOf(element) < 0);

It’s not working for me yet. I haven’t figured out how to correctly implement it.

@camperextraordinaire Here it is using includes .

const destroyer = (arr, ...args) => arr.filter((element) => !args.includes(element));

Thank you again for help with this!

@camperextraordinaire

So if we use splice to remove the element from the first array then each successive argument would be searching against a continuously shorter first array as the elements are removed?

I read through the Wikipedia link and the intent seems to be to retain data from each operation in the function and each “recursion” would require less time to execute.

@camperextraordinaire I’m not creating the lookup object correctly and I know below isn’t correct. Can you tell me if I’m way off base here?

function destroyer(arr, ...args) {
  let look = [];
  for (let j=0; j<args.length; j++) {
    look.args[j];
  }
  var filtered = [];
  for (let i=0; i<arr.length; i++) {
    if (look[arr[i]]) {filtered.push(arr[i])};
  }
  return filtered;
}

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

@camperextraordinaire The following solution works. I’m not confident it is fully accomplishing what you are describing above. It’s also probably not the most concise solution.

function destroyer(arr, ...args) {
  let look = {};
  for (let j=0; j<args.length; j++) {
    Object.defineProperty(look, args[j], {value:true});
  }
  var filtered = [];
  for (let i=0; i<arr.length; i++) {
    if (!look[arr[i]]) {filtered.push(arr[i])};
  }
  console.log();
  return filtered;
}

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

This is an interesting thread!

I would be most interested to see where this finishes up and get Randell’s solution using a lookup object. Did you work it out for a solution that can handle very large arrays/args?