Why does true work here in place of null?

Tell us what’s happening:
The last line works with either return arr.filter(item => item !== null) or return arr.filter(item => item !== true). The first filters out the null values, which makes sense. Why would filtering out the true values accomplish the same thing?
Your code so far


function destroyer(arr) {
let valsToRemove = Object.values(arguments).slice(1);
for(let i = 0; i < arr.length; i++) {
  for(let j = 0; j < valsToRemove.length; j++) {
      if(arr[i] === valsToRemove[j]) {
        delete(arr[i]);
      }
  }
} 

return arr.filter(item => item !== true);
}

console.log(destroyer([1, 2, 3, 5, 1, 2, 3], 2, 3));
  **Your browser information:**

User Agent is: Mozilla/5.0 (X11; CrOS x86_64 13421.102.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.199 Safari/537.36.

Challenge: Seek and Destroy

Link to the challenge:

1 Like

filter skips the empty elements (the callback is not invoked).

MDN: filter

callback is invoked only for indexes of the array which have assigned values; it is not invoked for indexes which have been deleted or which have never been assigned values.

const arr = [1, 2, 3, true, false, null];
delete arr[0];

console.log(arr); // [ , 2, 3, true, false, null ]
console.log(arr.filter((ele) => ele)); // [ 2, 3, true ]
3 Likes

true and “truthy” are not exactly the same. .filter(item => item !== true) will remove only items that have the actual value of true.

.filter(item => item !==null) will remove only items that have the actual value of null.

1 Like

Yes, what lasjorg said. If I do this:

  // ...
  console.log('arr before filter', arr)
  return arr.filter((item) => {
    console.log('item in loop', item, item !== true)
    return true;
  });
}
console.log(destroyer([1, 2, 3, 5, 1, 2, 3], 2, 3));

I get:

arr before filter (7) [1, empty × 2, 5, 1, empty × 2]
item in loop 1 true
item in loop 5 true
item in loop 1 true
[1, 5, 1]

So, like lasjorg says, those values aren’t even making it into your loop, so filter only gets to return the iterable elements, making a new array out of them.

Technically you could have done item => item !== 'elephant pajamas' with the same effect. All it needs is something that will return true in every case. You could have had () => true. So really, with the filter effect that lasjorg mentioned, all you’re really doing here is copying the array without the empty elements. The empty elements were created by your delete. When you delete an array element, it just leaves an empty slot, it doesn’t reindex the entire array.

Personally I don’t like using delete on arrays because I think it is an odd, counterintuitive behavior. But it is very self-contained here so maybe it’s OK.

2 Likes