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


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.