freeCodeCamp: Seek and Destroy Algorithm System Bug

Challenge Seek and Destroy has an issue. User Agent is: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36. Please describe how to reproduce this issue, and include links to screenshots if possible.

My code:

function isequal(value) {
  return value !== this;}
function destroyer(arr) {
  filtered = arguments[0];
  for (i=1; i<arguments.length; i++){
    filtered = filtered.filter(isequal,arguments[i]);
  }
  return filtered;
}

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

Although my code above returns all the correct output and passes all the tests, the system will not let me proceed to the next challenge. It marks all the tests as failed. Seems to be a bug.

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Comments: 33 (20 by maintainers)

Most upvoted comments

Just went through, the thread, I think this should be closed as an edge case with the camper’s code. I agree detecting such code is costly, and adding any instructions will cause confusion to users.

Closing. Feel free to continue the discussion or re-open, but in my honest opinion, this should be left as it is.

One other solution I just found is to change the comparative operator from !== to != If you are not using a strict comparison operator it will work.

@parisclinkscales

I looked at your code, and this is the fix:

function seeker (value){
  return value !== this.valueOf(); // 'this' is an object, so you need to call valueOf method
}

function destroyer(arr) {
  var filtered = arguments[0];
  for (var i = 1;i < arr.length;i++){
    filtered = filtered.filter(seeker,arguments[i]);
    }
  return filtered;
  }

@systimotic @parisclinkscales @Bouncey This is an easy-to-read solution:

function destroyer(arr) {
  var args = [];
  for(var i in arguments) { // gets all arguments and save them for the callback
    args.push(arguments[i]);
  }

  function isEqual(element){ // when you create a new function, a new arguments object is created
    for (var j = 1; j < args.length; j++){
      if(element == args[j]){
        return false;
      }
    }
    return true;
  }

  return arr.filter(isEqual);       
}

And cleaner solution:

function destroyer(arr) {
  return arr.filter(function(value) {
    return !this.includes(value);
  }, Array.prototype.slice.call(arguments, 1));
}

I’ve delved into this issue a bit more. Going from @elisecode247’s and @kevcomedia’s findings, here’s what I found. The second argument of Array.prototype.filter is the optional thisArg. If you pass an object, it will set this inside the callback. Without 'use strict';, this can only be an object. If what’s passed as the thisArg isn’t an object, it will set this to an empty object. With 'use strict;', this is no longer forced to be an object. It can now be set to a number. My source is Elise’s MDN article, a bit further down. @Bouncey I think this issue can be closed, as it was a code problem (a difficult one though). I’d love to hear your thoughts though. Maybe the description should be altered in some way to make people aware of this problem.

I want to work on this.

Check this out. It turns out isequal changes arguments[i] into a Number object, so the value !== this means value is compared to an object, and so it always returns true.

So the campers test case is running twice?

I logged value and this in isEqual and that seemed fine.

@BKinahan as for your Result : ¯\_(ツ)_/¯ that’s just weird