Перетворити булевий результат у число / ціле число


276

У мене є змінна, яка зберігає falseабо true, але мені потрібно 0або 1замість цього відповідно. Як я можу це зробити?


8
Ось порівняння ефективності деяких із наданих методів: jsperf.com/conversion-from-boolean-to-number .
— Сем

4
Користувачі Node.JS захочуть користуватися bool === true ? 1 : 0, оскільки він на сьогоднішній день найшвидший у V8.
— Qix - МОНІКА ПОМИЛИЛА

3
або простоbool ? 1 : 0;
— Атрахасіс

Відповіді:


343

У Javascript є потрійний оператор, який ви можете використовувати:

var i = result ? 1 : 0;

7
Найкраща відповідь. Чому? Це працює на правдивості, яка є більш загальною і приймає будь-який тип (рядок, число, тощо). Одинарна відповідь справді розумна, але якщо я передаю її рядок, вона повертається NaN. Тож, якщо ви хочете L33T і гарантуєте вхід, перейдіть на порядок, інакше найкращим є тест на потрійний + truthy.
— gdibble

465

Використовуйте одинарний +оператор , який перетворює його операнд у число.

+ true; // 1
+ false; // 0

Зверніть увагу, звичайно, що вам все-таки слід очистити дані на стороні сервера, оскільки користувач може надсилати будь-які дані вашій суворому сервісу, незалежно від того, що говорить клієнтський код.


50
Хоча круто (я ніколи про це не думав), це неймовірно повільно (на 97% повільніше в Chrome, якщо бути точним). Будьте обережні!
— Qix - МОНІКА ПОМИЛИЛИ

5
Ознайомтеся з цією редакцією . Number()ще повільніше.
— Qix - МОНІКА ПОМИЛИЛА

23
Здається, bool === true ? 1 : 0це найшвидше, з близькою секундою від bool | 0.
— Qix - МОНІКА ПОМИЛИЛА

1
Помноження (наприклад, 3 * false) відчуває себе так неправильно, але воно працює. :) Дякую!
— mattsoave

1
@DerkJanSpeelman Те, що щось не дозволено в Typescript, не означає, що ви не повинні робити це в Javascript. Вони різні (хоч і споріднені) мови.
— самотній день

119

Найкраще рішення:

fooBar | 0

Це використовується в asm.js для примусового цілого типу.


Один з найшвидших; +1.
— Qix - МОНІКА ПОМИЛИЛА

3
Хороший. Також ви можете використовувати "логічний ^ 0". АБО чи XOR працює.
— F8ER

Це не поверне 1ціле число, чи не буде fooBar?
— ESR

58

Я вважаю за краще використовувати функцію Число . Він бере об’єкт і перетворює його в число.

Приклад:

var myFalseBool = false;
var myTrueBool = true;

var myFalseInt = Number(myFalseBool);
console.log(myFalseInt === 0);

var myTrueInt = Number(myTrueBool);
console.log(myTrueInt === 1);

Ви можете перевірити його у jsFiddle .


3
Це найкраща відповідь на сьогоднішній день. Внизу звичайно. Тільки "він бере предмет" невірно.
— Rudie

2
Посилання на mdn набагато краще, ніж w3schools (eeek!): Developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
— Olivvv

Я думаю, що це найкращий спосіб, тому що це легко читати та розкривати наміри.
— Сем

3
Це також повільніше.
— Qix - МОНІКА ПОМИЛИЛА

45

Я створив JSperf порівняння всіх запропонованих відповідей .

TL; DR - найкращий варіант для всіх поточних браузерів:

val | 0;

.

Оновлення:

Схоже, в ці дні всі вони досить однакові, за винятком того, що Number()функція є найповільнішою, тоді як найкраща val === true ? 1 : 0;.


2
Цікаво, що тернар зараз найшвидший у Chrome 64.0.3282 на macOS 10.13.3.
— 2540625

Це був би найшвидший варіант на той час. Це відрізняється від того, що це найкращий варіант.
— mikemaccana


30

Я щойно натрапив на цей ярлик сьогодні.

~~ (правда)

~~ (помилково)

Люди набагато розумніші, ніж я можу пояснити:

http://james.padolsey.com/javascript/double-bitwise-not/


2
Цікаво. Я дізнався щось нове сьогодні. Я не буду використовувати цю техніку в жодному проекті, тому що її потенціал може заплутати майбутніх або колег.
— nicholaides

1
hacky js - це моя фаворит. серйозно, +1
— Тодд

16

Коли 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.


13

Одинарний +оператор подбає про це:

var test = true;
// +test === 1
test = false;
// +test === 0

Ви, природно, захочете перевірити це на сервері перед тим, як зберігати його, щоб це все-таки було розумнішим місцем для цього.


Я змінив коментарі ===, тому що true == 1це правда навіть без вас, "явна конверсія :-) true === 1замість цього помилкова.
— xanatos

13

Я просто займався цим питанням в якомусь коді, який я писав. Моє рішення полягало в тому, щоб використовувати побіжно і.

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;
}});

У мене було дві голоси на цю посаду. Чому б вам не пояснити, чому ви спростували це? В іншому випадку це просто потік без обґрунтування.
— Ніколас Р. Грант

1
У 99 разів результати jsperf просто приводять вас до шляху передчасної оптимізації, оптимізуючи наносекунди з циклу, коли вам слід зосередитись на цьому потворному операторі SQL. дякую за надання кількох різних способів наблизитись до цього
— RozzA

Що таке оператор SQL? Тут немає жодного запиту. Якщо ви маєте на увазі JSPerf, я пов'язував це з чужого тесту. Це не моя власна. Я, чесно кажучи, не байдуже щодо продуктивності цього аспекту, оскільки це нічого не стосується. Я створив свою власну мову, яка майже була функціональною ідентичною JS, і я пам’ятаю, що передача до int була дурно швидкою операцією. Піднімаючись прототипом ланцюгів не було. Ось чому я все-таки рекомендую перший спосіб, як я це зробив, з простою функцією, яку може накреслити компілятор.
— Ніколас Р. Грант

річ SQL 'має узагальнення. дякую за розуміння
— RozzA

9

Ви також можете додати 0, використовувати оператори зміни або xor:

val + 0;
val ^ 0;
val >> 0;
val >>> 0;
val << 0;

Вони мають схожі швидкості, як і відповіді інших.


6

У моєму контексті React Native, де я отримую значення непрозорості від булевого, найпростіший спосіб: Використовуйте оператор unary +.

+ true; // 1
+ false; // 0

Це перетворює булеве число в число;

style={ opacity: +!isFirstStep() }

4

Ви можете це зробити, просто розширивши булевий прототип

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 як його вихід.




1

Я перевірив усі ці приклади, зробив орієнтир, і, нарешті, рекомендую вибрати коротший, він не впливає на продуктивність.

Запускається на сервері 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

0

якщо ви хочете змінити ціле число x, якщо 1 на 0, а якщо 0 на 1, ви можете використовувати (x + 1)% 2

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.