Everything Be True - failing last testcase

Can someone tell me why I am failing the last testcase whenever I have this bit of code in?

isNaN(collection[i][pre]) == true

Testcase that fails WITHOUT this code:
truthCheck([{"single": "double"}, {"single": NaN}], "single")

All code:

function truthCheck(collection, pre) {

  let flag = true;
  //Check if pre exists as a property in any of the objects that are in collection

  for(var i = 0; i<collection.length; i++){
    if(collection[i].hasOwnProperty(pre)){
       if(collection[i][pre] == false || collection[i][pre] == 0 || collection[i][pre] == null || collection[i][pre] == undefined || isNaN(collection[i][pre]) == true){
         flag = false;
       }
    }else{
      flag = false;
    }
  }
  return flag;

Testcases that fail WITH the NaN code in:
truthCheck([{"user": "Tinky-Winky", "sex": "male"}, {"user": "Dipsy", "sex": "male"}, {"user": "Laa-Laa", "sex": "female"}, {"user": "Po", "sex": "female"}], "sex")

and

truthCheck([{"single": "yes"}], "single")

I’m sure there is some pattern to why these fail when I add the NaN code in versus when I take it out, but I can’t figure it out.

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

So you may be overthinking just a little bit. Think about the logic of this – you’re saying “if collection[i][pre] is falsy in any way, set flag to false”. But you’re manually checking every possible combination of “is falsy”. Is this strictly necessary?

if (false)
if (null)
if (undefined)
if (0)
if (NaN)
if ('')
if ("")
if (``)
if (document.all)

Those all evaluate as false. So, assuming some variable, let’s call it value is set to ANY of those, then simply checking if(value) will return false. Or, conversely, if(!value) will invert that, and evaluate as true. You may be more likely to want that second case, as that would read “IF it is TRUE that value is set to something FALSY…”

Wow that’s confusing.

But can you think of a way that might simplify your code?

I have to admit, I find the concept of falsey a little confusing. Or rather, I find the concept of checking for falsey very confusing.

I understood everything you said until the example using value. Why couldn’t I just check to see if value is any of those values in your list…? (Insert “still confused” emoji here). The way I understand it, falsey is just a term to denote all the “non-values”, for lack of a better term, you listed. So why not just check for them…?

Having said all that, I went back to my code and (did some more googling about falsey) and ended up with something new. This time, all test-cases passed. But I suspect it can be streamlined. In the meantime, am adding falsey to my list of JS concepts that I need to continue to strengthen.

Thank you! And any feedback on new code is welcome.

function truthCheck(collection,pre){

  let flag = true;

  for(var i = 0; i< collection.length; i++){
    if (collection[i].hasOwnProperty(pre)) {
      if(collection[i][pre]){
        flag = true;
      }else {
        flag = false;
        break;
      }
    }else{
      flag = false;
      break;
    }
  }
  return flag;
}
1 Like

In the new version of your code you have 2 if lines one after the other. You can use && to combine the 2 conditions. This will help you get ride of the last else clause as well (DRY code).

A good practice is to make a variable with a descriptive name for the interior of the if logical clause:

const element = collection[i];
const is_pre_truthy = element.hasOwnProperty(pre) && element[pre];
if (is_pre_truthy) {
...
}

In case the predicate pre is not in element, the first part of the condition will fail. The second part of the condition is not evaluated in this case, so it will no cause the code to fail.
This is a good trick to avoid nesting if statements.

EDIT: You can also revert the if and else logic to make the code even more concise.

1 Like