Equality Operator Confusion

I was asked to create a function that will be given an array of numbers. The set of numbers will either be all even numbers with one odd number, or all odd numbers with one even number.

The function needs to find this outlier number and return it.
My work:

var detectOutlierValue = function (array) {
    // Implement your code below
    posArr = array.filter(x => x%2 === 0);
    negArr = array.filter(x => x%2 === 1);
    if (negArr.length = 1) {
        return Number(negArr);
    } 
    if (posArr.length = 1) {
        return Number(posArr);
    }
  }
  
  console.log(detectOutlierValue([1, 3, 4, 7, 9, 11]));
  // should be 4
  console.log(detectOutlierValue([2, 4, 6, 10, 11, 14]));
  // should be 11

The code as is prints 1 (incorrect) for the posArray and 11 (which is correct) for the negArr.

Now I know it’s because I used the “=” operator instead of a “==” or “===” operator in the conditional statements.

Could someone explain to me why the code provided was return posArr as 1? And when I should ever use a “=” vs “==” operator? I feel like understanding this behavior will help me understand JS.

1 Like

Use “=” to set the value that you store in a variable or constant.
Use “==” or “===” to check to see if the value on the left and right of the equal sign are the same.

1 Like

Also what is this function suppose the to return. Just curious.

Good luck with it!

1 Like

That is essentially correct, but just to elaborate on the difference between == and ===

The equality operator (==, sometimes called “weak” equality) will try to make a type conversion if necessary. If I have:

123 == 123
// true

'123' == '123'
// true

Those make perfect sense - they are the same type so comparing them is easy. But what about:

123 == '123'
// true

Is the number 123 the same as the string '123'? Not really. But the equality operator will see that they are different types. It sees that one is a string and one is a number so it will try to coerce that string to a number. It coerces the string '123' to the number 123 so it says that they are now equal. That is what the equality operator does - it coerces one of the values if the types don’t match and compares that.

The strict equality operator (===) does no coercion. If the types don’t match then they are not strictly equal, no matter what - they can never be strictly equal. So:

123 == '123'
// true

123 === '123'
// false

In general, use the strictly equal (===). It’s faster and safer. I’ve seen more than a few bugs because people used the == operator and an unexpected coercion was taking place. Just use the strictly equal and if there is a conversion needed, do it yourself - it will be safer and easier to read, imho.

1 Like

You have some really funny stuff going on in your code, it’s failing in almost spectacular ways. People have already explained the fundamental difference between the assignment operator (=) and the comparison operators (== and ===), but to help you understand why you get the output you have:

Your code is fine up to this point (except that you’re not declaring your variables):

var detectOutlierValue = function (array) {
    // Implement your code below
    posArr = array.filter(x => x%2 === 0);
    negArr = array.filter(x => x%2 === 1);
  }

Then you hit the first if statement. It expects a comparison, but you’re making an assignment to 1, which is a valid array length, so it evaluates to a truthy value. So the first if statement is always true, and from there, you exit the function with return Number(negArr).
The second if statement is never evaluated, it’s “unreachable code”. The function will always return Number(negArr).


If you feed your function with [1,3,4,7,9,11], negArr will be [1,3,7,9,11].

Then you hit the if statement, where you set the length of the array to 1. You’re not making a comparison, instead you’re setting the value of the array’s length. If you have an array ['A','B','C'] and set its length to 1, the result is this: ['A']. So when you enter the if block, your negArr is this: [1].

Then you return Number(negArr). JavaScript is forgiving, so it doesn’t throw an error when you try to convert an Array to a Number. If your array would be longer than just one item, or if JavaScript would find no way to coerce that one item into a number, you’d get NaN (Not a Number). But you’re using Number() on an array with only one item in it ([1]), which happens to be a number, so JavaScript kindly returns that number.


Second case - you feed your function with [2, 4, 6, 10, 11, 14].
negArr will be [11].

It hits the if statement, setting the length to 1 will do nothing because the length is already 1, and it’ll return whatever it thinks that Number([11]) should evaluate to, which is 11.


So, congratulations, i’ve rarely seen code failing so epically :love_you_gesture:
Did you accidentally come up with that yourself, or is that an interview question?

lol

Cool , That makes sense to me now why it was returning 1.

This was a test question and I was only asked to return the one outlier(an odd or even number), so my logic was to simply return the array that had one number in it after the filter methods by using the if statements.

I long since changed the “=” to “===” and it passed the test. While I know there are much better ways of writing it, it does what I was asked and it works so :woozy_face: