Преобразовать логический результат в число / целое число
У меня есть переменная, которая хранит false
или же true
, но мне нужно 0
или же 1
вместо соответственно. Как я могу это сделать?
23 ответа
Javascript имеет троичный оператор, который вы можете использовать:
var i = result ? 1 : 0;
Используйте одинарный +
оператор, который преобразует свой операнд в число.
+ true; // 1
+ false; // 0
Обратите внимание, конечно, что вы все равно должны санировать данные на стороне сервера, потому что пользователь может отправлять любые данные на ваш сервер, независимо от того, что говорит код на стороне клиента.
Imho лучшее решение:
fooBar | 0
Это используется в asm.js для принудительного использования целочисленного типа.
Я предпочитаю использовать функцию Number. Он берет объект и преобразует его в число.
Пример:
var myFalseBool = false;
var myTrueBool = true;
var myFalseInt = Number(myFalseBool);
console.log(myFalseInt == 0);
var myTrueInt = Number(myTrueBool);
console.log(myTrueInt == 1);
Или запустите его в jsFiddle.
Типизированный способ сделать это будет:
Number(true) // 1
Number(false) // 0
Я создал JSperf сравнение всех предложенных ответов.
TL; DR - лучший вариант для всех существующих браузеров:
val | 0;
,
Обновить:
Кажется, что в наши дни все они довольно идентичны, за исключением того, Number()
функция самая медленная, а самая лучшая val === true ? 1 : 0;
,
Я только что наткнулся на этот ярлык сегодня.
~~ (истина)
~~ (ложь)
Люди намного умнее, чем я могу объяснить
TL;DR: Избегайте
Number
конструктор, одинарный; все время используйте простой; прибегать к или
1 * bool
если бенчмарки в вашем проекте работают лучше.
Это довольно старый вопрос, и на него есть много правильных ответов. Что - то я заметил, что все тесты здесь не имеют никакого отношения - ни принимать во внимание ветви предсказания . Кроме того, в настоящее время движки JS не просто интерпретируют код, они JIT компилируют его в собственный машинный код и оптимизируют его перед выполнением. Это означает, что, помимо предсказания ветвлений, компилятор может даже заменять выражения их окончательным значением.
Теперь, как эти два фактора влияют на производительность преобразования логических значений в целые числа? Давай выясним! Прежде чем мы перейдем к тестам, важно знать, что мы тестируем. Для преобразования мы используем следующие семь методов преобразования:
- Конструктор чисел:
- Если оператор (используется троичный):
bool ? 1 : 0
- Унарный оператор
+
: - Побитовое ИЛИ:
bool | 0
- Побитовое И:
bool & 1
- Побитовое двойное НЕ:
~~bool
- Умножение чисел:
bool * 1
«Преобразование» означает преобразование
false
к
0
и чтобы
1
1 . Каждый метод преобразования выполняется 100000 раз, количество операций измерения / миллисекунда. В следующих таблицах методы преобразования будут соответственно сгруппированы по их результатам. Результаты получены на моей машине с процессором AMD Ryzen 7 4800HS.
Первый тест преобразует постоянную
true
:
Непредвиденный? Ожидал? Я бы сказал второе, потому что в этом случае предсказание ветвления было успешным почти во всех случаях, учитывая крошечную разницу между троичным if и побитовым взломом. Все остальные результаты такие же, здесь больше не о чем говорить.
Это усилие возвращает нас к исходному вопросу: как преобразовать bool в int в Javascript? Вот мои предложения:
- Избегать
Number(bool)
и+bool
. Эти два метода выполняют много внутренней работы, и хотя Chrome удалось оптимизировать их в наших тестах, Firefox этого не сделал, и могут быть некоторые ситуации, когда эти оптимизации не будут выполняться компилятором. Кроме того, не все пользуются Chrome! Мне все еще приходится с этим мириться, а тебе? ... - Как правило, используйте операторы if. Не умничайте - браузер обычно работает лучше и обычно означает большинство ситуаций. Они являются наиболее удобочитаемыми и понятными из всех представленных здесь методов. Пока мы находимся на читабельности, возможно
if (bool)
вместо этой уродливой троицы! Я бы хотел, чтобы в Javascript было то, что есть в Rust или Python ... - Остальное используйте, когда это действительно необходимо. Может быть, тесты в вашем проекте не соответствуют стандартам, и вы обнаружили, что
if
вызывает плохую производительность - в таком случае, не стесняйтесь заниматься внетелевым программированием ! Но не заходите слишком глубоко в кроличью нору, никто не выиграет от таких вещей, как-1 * (a < b) + 1 * (a > b)
, Поверьте мне.
Я буду бесконечно благодарен вам за то, что вы дочитали до конца - это мой первый более продолжительный и значительный ответ на StackOverflow, и это значит для меня весь мир, если он был полезным и проницательным. Если вы обнаружите какие-либо ошибки, не стесняйтесь исправлять меня!
- Определил преобразование, потому что не совсем ясно, что означает логическое значение в целое число. Например, Go вообще не поддерживает это преобразование .
Когда JavaScript ожидает числовое значение, но вместо этого получает логическое значение, он преобразует это логическое число в число: true и false преобразуются в 1 и 0 соответственно. Таким образом, вы можете воспользоваться этим;
var t = true;
var f = false;
console.log(t*1); // t*1 === 1
console.log(f*1); // f*1 === 0
console.log(+t); // 0+t === 1 or shortened to +t === 1
console.log(+f); //0+f === 0 or shortened to +f === 0
Дальнейшее чтение Преобразования типов Глава 3.8 Полное руководство по Javascript.
Я просто имел дело с этой проблемой в каком-то коде, который писал. Моим решением было использовать побитовое и.
var j = bool & 1;
Более быстрый способ справиться с постоянной проблемой - создать функцию. Это лучше читается другими людьми, лучше для понимания на этапе обслуживания и избавляет от возможности написать что-то не так.
function toInt( val ) {
return val & 1;
}
var j = toInt(bool);
Изменить - 10 сентября 2014
По какой-то причине в Chrome не выполняется преобразование с использованием троичного оператора с идентичным оператору. Не имеет смысла, почему это быстрее, но я полагаю, что это своего рода оптимизация низкого уровня, которая имеет смысл где-то по пути.
var j = boolValue === true ? 1 : 0;
Проверьте сами: http://jsperf.com/boolean-int-conversion/2
В FireFox и Internet Explorer использование размещенной мной версии обычно происходит быстрее.
Изменить - 14 июля 2017 г.
Хорошо, я не собираюсь говорить вам, какой из них вы должны или не должны использовать. Каждый взбесившийся браузер все время показывал, насколько быстро они могут выполнять операции с каждым методом. В какой-то момент у Chrome битовая версия работала лучше, чем у других, но вдруг все стало намного хуже. Я не знаю, что они делают, поэтому я просто оставлю это тем, кого это волнует. Существует редкая причина заботиться о том, как быстро выполняется такая операция. Даже на мобильном телефоне это пустая операция.
Кроме того, вот более новый метод для добавления прототипа toInt, который не может быть перезаписан.
Object.defineProperty(Boolean.prototype, "toInt", { value: function()
{
return this & 1;
}});
Одинарный +
Оператор позаботится об этом:
var test = true;
// +test === 1
test = false;
// +test === 0
Вы, естественно, захотите проверить это на сервере перед сохранением, так что в любом случае это может быть более разумным местом для этого.
Вы также можете добавить 0, использовать операторы shift или xor:
val + 0;
val ^ 0;
val >> 0;
val >>> 0;
val << 0;
Они имеют те же скорости, что и ответы других.
В моем контексте, React Native, где я получаю значение непрозрачности от логического, самый простой способ: использовать унарный оператор +.
+ true; // 1
+ false; // 0
Это преобразует логическое число в число;
style={ opacity: +!isFirstStep() }
+!!
позволяет применить это к переменной, даже если она
undefined
:
+!!undefined // 0
+!!false // 0
+!!true // 1
+!!(<boolean expression>) // 1 if it evaluates to true, 0 otherwise
Преобразование логического значения в целое число в JavaScript можно выполнить следующими способами:
- С использованием
Number()
- Использование унарных операторов
- Использование арифметических операторов
- Использование побитовых операторов
- Использование операторов побитового сдвига
В предыдущих ответах некоторые из них уже были рассмотрены, однако вы можете найти некоторые из них, которые отсутствуют следующим образом:
// using arithmetic operators
true + 0; // 1
false + 0; // 0
true - 0; // 1
false - 0; // 0
true * 1 // 1
false * 1 // 0
true / 1; // 1
false / 1; // 0
// using bitwise operators
true & 1; // 1
false & 1; // 0
true | 0; // 1
false | 0; // 0
true ^ 0; // 1
false ^ 0; // 0
// using bitwise shift operators
true >> 0; // 1
false >> 0; // 0
true >>> 0; // 1
false >>> 0; // 0
true << 0; // 1
false << 0; // 0
Они работают, потому что JavaScript внутренне приводит логические значения к их целочисленным эквивалентам при выполнении этих операций.
Важно отметить, что все эти методы (за исключением Использование тернарногоиспользования тернарного оператора ) потенциально могут возвращатьNaN
когда вы не уверены, что переменная всегда имеет логическое значение.
Написал сообщение в блоге для тех, кто хочет узнать больше.
Пытаться
val*1
let t=true;
let f=false;
console.log(t*1);
console.log(f*1)
Вы можете сделать это, просто расширив логический прототип
Boolean.prototype.intval = function(){return ~~this}
Нелегко понять, что там происходит, поэтому альтернативная версия будет
Boolean.prototype.intval = function(){return (this == true)?1:0}
сделав что вы можете сделать такие вещи, как
document.write(true.intval());
Когда я использую логические значения для хранения условий, я часто конвертирую их в битовые поля, и в этом случае я использую расширенную версию функции-прототипа.
Boolean.prototype.intval = function(places)
{
places = ('undefined' == typeof(places))?0:places;
return (~~this) << places
}
с помощью которого вы можете сделать
document.write(true.intval(2))
который производит 4 в качестве своего выхода.
Я протестировал все эти примеры, сделал тест и, наконец, рекомендую выбрать более короткий, он не влияет на производительность.
Работает на сервере Ubuntu 14.04, nodejs v8.12.0 - 26/10/18
let i = 0;
console.time("TRUE test1")
i=0;
for(;i<100000000;i=i+1){
true ? 1 : 0;
}
console.timeEnd("TRUE test1")
console.time("FALSE test2")
i=0;
for(;i<100000000;i=i+1){
false ? 1 : 0;
}
console.timeEnd("FALSE test2")
console.log("----------------------------")
console.time("TRUE test1.1")
i=0;
for(;i<100000000;i=i+1){
true === true ? 1 : 0;
}
console.timeEnd("TRUE test1.1")
console.time("FALSE test2.1")
i=0;
for(;i<100000000;i=i+1){
false === true ? 1 : 0;
}
console.timeEnd("FALSE test2.1")
console.log("----------------------------")
console.time("TRUE test3")
i=0;
for(;i<100000000;i=i+1){
true | 0;
}
console.timeEnd("TRUE test3")
console.time("FALSE test4")
i=0;
for(;i<100000000;i=i+1){
false | 0;
}
console.timeEnd("FALSE test4")
console.log("----------------------------")
console.time("TRUE test5")
i=0;
for(;i<100000000;i=i+1){
true * 1;
}
console.timeEnd("TRUE test5")
console.time("FALSE test6")
i=0;
for(;i<100000000;i=i+1){
false * 1;
}
console.timeEnd("FALSE test6")
console.log("----------------------------")
console.time("TRUE test7")
i=0;
for(;i<100000000;i=i+1){
true & 1;
}
console.timeEnd("TRUE test7")
console.time("FALSE test8")
i=0;
for(;i<100000000;i=i+1){
false & 1;
}
console.timeEnd("FALSE test8")
console.log("----------------------------")
console.time("TRUE test9")
i=0;
for(;i<100000000;i=i+1){
+true;
}
console.timeEnd("TRUE test9")
console.time("FALSE test10")
i=0;
for(;i<100000000;i=i+1){
+false;
}
console.timeEnd("FALSE test10")
console.log("----------------------------")
console.time("TRUE test9.1")
i=0;
for(;i<100000000;i=i+1){
0+true;
}
console.timeEnd("TRUE test9.1")
console.time("FALSE test10.1")
i=0;
for(;i<100000000;i=i+1){
0+false;
}
console.timeEnd("FALSE test10.1")
console.log("----------------------------")
console.time("TRUE test9.2")
i=0;
for(;i<100000000;i=i+1){
-true*-1;
}
console.timeEnd("TRUE test9.2")
console.time("FALSE test10.2")
i=0;
for(;i<100000000;i=i+1){
-false*-1;
}
console.timeEnd("FALSE test10.2")
console.log("----------------------------")
console.time("TRUE test9.3")
i=0;
for(;i<100000000;i=i+1){
true-0;
}
console.timeEnd("TRUE test9.3")
console.time("FALSE test10.3")
i=0;
for(;i<100000000;i=i+1){
false-0;
}
console.timeEnd("FALSE test10.3")
console.log("----------------------------")
console.time("TRUE test11")
i=0;
for(;i<100000000;i=i+1){
Number(true);
}
console.timeEnd("TRUE test11")
console.time("FALSE test12")
i=0;
for(;i<100000000;i=i+1){
Number(false);
}
console.timeEnd("FALSE test12")
console.log("----------------------------")
console.time("TRUE test13")
i=0;
for(;i<100000000;i=i+1){
true + 0;
}
console.timeEnd("TRUE test13")
console.time("FALSE test14")
i=0;
for(;i<100000000;i=i+1){
false + 0;
}
console.timeEnd("FALSE test14")
console.log("----------------------------")
console.time("TRUE test15")
i=0;
for(;i<100000000;i=i+1){
true ^ 0;
}
console.timeEnd("TRUE test15")
console.time("FALSE test16")
i=0;
for(;i<100000000;i=i+1){
false ^ 0;
}
console.timeEnd("FALSE test16")
console.log("----------------------------")
console.time("TRUE test17")
i=0;
for(;i<100000000;i=i+1){
true ^ 0;
}
console.timeEnd("TRUE test17")
console.time("FALSE test18")
i=0;
for(;i<100000000;i=i+1){
false ^ 0;
}
console.timeEnd("FALSE test18")
console.log("----------------------------")
console.time("TRUE test19")
i=0;
for(;i<100000000;i=i+1){
true >> 0;
}
console.timeEnd("TRUE test19")
console.time("FALSE test20")
i=0;
for(;i<100000000;i=i+1){
false >> 0;
}
console.timeEnd("FALSE test20")
console.log("----------------------------")
console.time("TRUE test21")
i=0;
for(;i<100000000;i=i+1){
true >>> 0;
}
console.timeEnd("TRUE test21")
console.time("FALSE test22")
i=0;
for(;i<100000000;i=i+1){
false >>> 0;
}
console.timeEnd("FALSE test22")
console.log("----------------------------")
console.time("TRUE test23")
i=0;
for(;i<100000000;i=i+1){
true << 0;
}
console.timeEnd("TRUE test23")
console.time("FALSE test24")
i=0;
for(;i<100000000;i=i+1){
false << 0;
}
console.timeEnd("FALSE test24")
console.log("----------------------------")
console.time("TRUE test25")
i=0;
for(;i<100000000;i=i+1){
~~true;
}
console.timeEnd("TRUE test25")
console.time("FALSE test26")
i=0;
for(;i<100000000;i=i+1){
~~false;
}
console.timeEnd("FALSE test26")
console.log("----------------------------")
console.time("TRUE test25.1")
i=0;
for(;i<100000000;i=i+1){
~true*-1-1;
}
console.timeEnd("TRUE test25.1")
console.time("FALSE test26.1")
i=0;
for(;i<100000000;i=i+1){
~false*-1-1;
}
console.timeEnd("FALSE test26.1")
console.log("----------------------------")
console.time("TRUE test27")
i=0;
for(;i<100000000;i=i+1){
true/1;
}
console.timeEnd("TRUE test27")
console.time("FALSE test28")
i=0;
for(;i<100000000;i=i+1){
false/1;
}
console.timeEnd("FALSE test28")
Результат
TRUE test1: 93.301ms
FALSE test2: 102.854ms
----------------------------
TRUE test1.1: 118.979ms
FALSE test2.1: 119.061ms
----------------------------
TRUE test3: 97.265ms
FALSE test4: 108.389ms
----------------------------
TRUE test5: 85.854ms
FALSE test6: 87.449ms
----------------------------
TRUE test7: 83.126ms
FALSE test8: 84.992ms
----------------------------
TRUE test9: 99.683ms
FALSE test10: 87.080ms
----------------------------
TRUE test9.1: 85.587ms
FALSE test10.1: 86.050ms
----------------------------
TRUE test9.2: 85.883ms
FALSE test10.2: 89.066ms
----------------------------
TRUE test9.3: 86.722ms
FALSE test10.3: 85.187ms
----------------------------
TRUE test11: 86.245ms
FALSE test12: 85.808ms
----------------------------
TRUE test13: 84.192ms
FALSE test14: 84.173ms
----------------------------
TRUE test15: 81.575ms
FALSE test16: 81.699ms
----------------------------
TRUE test17: 81.979ms
FALSE test18: 81.599ms
----------------------------
TRUE test19: 81.578ms
FALSE test20: 81.452ms
----------------------------
TRUE test21: 115.886ms
FALSE test22: 88.935ms
----------------------------
TRUE test23: 82.077ms
FALSE test24: 81.822ms
----------------------------
TRUE test25: 81.904ms
FALSE test26: 82.371ms
----------------------------
TRUE test25.1: 82.319ms
FALSE test26.1: 96.648ms
----------------------------
TRUE test27: 89.943ms
FALSE test28: 83.646ms
поддерживается во всех браузерах, поддерживает ввод как логическое значение или как строковое представление логического значения
var yourVarAsStringOrBoolean;
yourVarAsStringOrBoolean = "true"; //1
yourVarAsStringOrBoolean = "True"; //1
yourVarAsStringOrBoolean = "false"; //0
yourVarAsStringOrBoolean = false; //0
var resultAsInterger = Number(JSON.parse(yourVarAsStringOrBoolean.toString().toLowerCase()));
Используйте консоль Chrome, чтобы проверить это, это работает
Number(JSON.parse(false.toString().toLowerCase()));
Number(JSON.parse("TRUE".toString().toLowerCase()));
Поместите предлагаемые методы в jsben.ch:https://jsben.ch/d33N1.
В каждом тесте он дает разные результаты, но лучшими методами в каждом тесте являются побитовые операции:0|bool
/bool|0
//1&bool
/~~bool
.
Если вы хотите, чтобы целочисленное значение x изменилось, если от 1 до 0, а если от 0 до 1, вы можете использовать (x + 1) % 2
Я знаю, что немного опоздал, но вы можете использовать так называемый модуль. Оператор по модулю представлен символом процента (%) в JS. Его цель - отдать остаток. Итак, если бы мы разделили число на2%
, он будет искать все, что делится на 2. Если это не так, то у вас есть остаток 1, который всегда будет иметь место, так что вы знаете, что это нечетно. В этом случае, что вы собираетесь сделать, это сначала датьinteger
любое число, которое вы хотите, и в этом случае вам нужен или .
const integer = 0;
Если вы вставите1
он будет печататьfalse
пока0
будет печататьtrue
.
const isEven = (integer % 2) === 0;
if (isEven) {
console.log('true');
} else {
console.log('false');
}
Надеюсь, это поможет.