2016-10-16 6 views
0

Так что я делаю головоломки, чтобы оценить Kaprekar рутины и в первой части, мне нужно проверить, чтобы убедиться, что вход 4 цифры имеет по крайней мере два уникальных цифр, так что я сделал это:Почему этот набор логических операторов работает правильно?

let numArr = num.toString().split(""); 

if (numArr[0] == numArr[1] && numArr[2] && numArr[3]) { 
    return 0; 
} 

Я попытался найти но я продолжаю находить ссылки на операторов короткого замыкания. Я ожидал записать numArr [0] == в каждый блок & &, но, к моему удивлению, он сработал. Может ли кто-нибудь объяснить, почему это возвращает 0 для 3333, но не для 1234? Я предположил, что numArr [2] и numArr [3] просто оценили бы true автоматически.

+0

Строка с ненулевой длиной является правдой. Он не возвращает 0 для 1234, потому что '1' не равен '2'. – doug65536

+0

это тоже должно вернуть 0 для 1123. – vijayst

+0

'if (numArr [0] == numArr [1] && numArr.length> = 4)' будет делать то же самое, что и ваш код. – doug65536

ответ

2

Есть вещь, которая называется operator precedence. Сначала оператор с более высоким приоритетом. == происходит до &&. Когда у вас более одного оператора с одинаковым приоритетом, он переходит на «ассоциативность», которая, как правило, слева направо (=, например, справа налево); поэтому давайте еще раз взглянем на ваш код

if (((numArr[0] == numArr[1]) && numArr[2]) && numArr[3]) 

Давайте возьмем только первую часть. Выполнение 3 == 3 истинно, и поскольку ни один из операторов не равен 0, утверждение if истинно. Но с 1234, 1 == 2 ложно, поэтому выражение коротких замыканий на false. Обычно, когда что-то (например, оператор if) принимает логическое значение & & значение non zero/undefined/false, выражение считается истинным (возможно, я ошибаюсь). Если вы делаете ниже вы должны получить истинное

if (numArr[0] && numArr[1] && numArr[2] && numArr[3]) 

Чтобы ответить на другой вопрос, как правило, когда люди работают с набором данных в JS они используют lodash. Вы можете найти, если есть два уникальных значения с ударом линии. uniq (array, func) возвращает массив с уникальными значениями в том же порядке.See the documentation

_.uniq("3333".toString().split(""), v=>v).length >= 2 //false 
_.uniq("1224".toString().split(""), v=>v).length >= 2 //true 
0

Это происходит потому, что для струнного 3333 Num [0] = 3, Num [1] = 3, Num [2] = 3, Num [3] = 3

вычисления выражений на основе на приоритете операторов и когда операторы имеют одинаковый приоритет, они получают выполняются слева направо

в этом случае == имеет наивысший приоритет над & & так, Num [0] == Num [1], это 3 == 3 true затем истинно & & Num [2] & & Num [3] => истинно & & 3 => истинная

Для строки 1234 Num [0] = 1, NUM [1] = 2, Num [2] = 3, Num [3] = 4 Num [0] == Num [1], 1 == 2 является ложным так что теперь выражение является ложным & & Num [2] & & Num [3 ]

Для & & оператора, если первый операнд является ложным, то игнорировать остальную часть выражения так что теперь он просто приводит в качестве ложного

Надеется, что это помогает

0

У вас есть три выражений оцениваются

// 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] 

Все, что не Falsy (false, 0, "", null, undefined и NaN) является Truthy

Поэтому вам нужно написать дополнительный код для проверки уникальных цифр.

Смежные вопросы