简体   繁体   中英

Why does this set of logical operators work correctly?

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.

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

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM