Reputation: 1
So I'm doing a puzzle to evaluate Kaprekar's Routine and in the first section I need to check to make sure the 4 digit input has at least two unique digits so I did this:
let numArr = num.toString().split("");
if (numArr[0] == numArr[1] && numArr[2] && numArr[3]) {
return 0;
}
I tried searching but I keep finding links to short-circuiting operators. I was expecting to write out numArr[0] == into every && block but to my surprise it worked. Can anyone explain why this returns 0 for 3333 but does not for 1234? I assumed numArr[2] and numArr[3] would just evaluate to true automatically.
Upvotes: 0
Views: 70
Reputation:
There is a thing called operator precedence. The operator with higher precedence happens first. ==
happens before &&
. When you have more than one operator of the same precedence it goes by 'associativity' which is generally left to right (=
for example is right to left); so let's take another look at your code
if ( ((numArr[0] == numArr[1]) && numArr[2]) && numArr[3] )
Let's take just the first piece. Doing 3 == 3 is true and since none of the operators are 0, the if statement is true. But with 1234, 1 == 2 is false, so the expression short circuits to false. Generally when something (like an if statement) accepts a boolean value && a non zero/undefined/false value, the expression is considered true (I may be wrong). If you do the below you should get true
if ( numArr[0] && numArr[1] && numArr[2] && numArr[3] )
To answer your other question, generally when people work with a set of data in JS they use lodash. You can find the if there is 2 unique values easily with the line blow. uniq(array, func) returns an array with unique values in the same order. See the documentation
_.uniq("3333".toString().split(""), v=>v).length >= 2 //false
_.uniq("1224".toString().split(""), v=>v).length >= 2 //true
Upvotes: 2
Reputation: 2848
You have three expressions being evaluated
// loose-equality, so true if after type-coersion, the values are equivalent
// this is the only condition that is actually changing in your code, unless
// you have a number with less than 4 digits
numArr[0] == numArr[1]
// is a non-empty string so it's 'truthy'
numArr[2]
// is a non-empty string so it's 'truthy'
numArr[3]
Anything that is not Falsy (false
, 0
, ""
, null
, undefined
, and NaN
) is Truthy
Therefore, you need to write additional code to check for unique digits.
Upvotes: 0
Reputation: 7498
It is because For String 3333 num[0] is 3,num[1]=3,num[2]=3,num[3]=3
Expressions evaluate based on precedence of operators and when the operators have the same precedence they get executed from left to right
In this case == has highest precedence over && so, num[0]==num[1] ,it is 3==3 true then true && num[2] && num[3] => true&&3&&3 => true
For string 1234 num[0]=1,num[1]=2,num[2]=3,num[3]=4 num[0]==num[1] ,1==2 is false so now the expression is false && num[2] && num[3]
For && operator if the first operand is false,it ignore the rest of the expression so now it just results as false
Hope this helps
Upvotes: 0