Ubah hasil boolean menjadi angka / integer


276

Saya memiliki variabel yang menyimpan falseatau true, tetapi masing-masing saya butuh 0atau 1sebagai gantinya. Bagaimana saya bisa melakukan ini?


8
Berikut adalah perbandingan kinerja dari beberapa teknik yang disediakan: jsperf.com/conversion-from-boolean-to-number .
Sam

4
Pengguna Node.JS akan ingin menggunakan bool === true ? 1 : 0, karena sejauh ini yang tercepat di V8.
Qix - MONICA DISALAHKAN

3
atau hanyabool ? 1 : 0;
Atrahasis

Jawaban:


343

Javascript memiliki operator ternary yang dapat Anda gunakan:

var i = result ? 1 : 0;

7
Jawaban Terbaik. Mengapa? Ini bekerja pada kebenaran yang lebih umum dan menerima segala jenis (string, angka, dan sebagainya). Jawaban unary memang pintar, tetapi jika saya berikan string, ia kembali NaN. Jadi, jika Anda menginginkan L33T dan menjamin input, pilihlah urary, jika tidak, lakukan tes terner + truthy yang terbaik.
gdibble

466

Gunakan operator unary+ , yang mengubah operan menjadi angka.

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

Perhatikan, tentu saja, bahwa Anda masih harus membersihkan data di sisi server, karena pengguna dapat mengirim data apa pun ke server Anda, tidak peduli apa kata kode sisi klien.


50
Meskipun keren (saya tidak pernah memikirkan ini), ini sangat lambat (97% lebih lambat di Chrome, tepatnya). Berhati-hatilah!
Qix - MONICA DISALAHKAN

5
Lihatlah revisi ini . Number()bahkan lebih lambat.
Qix - MONICA DISALAHKAN

23
Tampaknya bool === true ? 1 : 0adalah yang tercepat, dengan sedetik dekat dari bool | 0.
Qix - MONICA DISALAHKAN

1
Mengalikan (mis. 3 * salah) terasa sangat salah, tetapi berhasil. :) terima kasih!
mattsoave

1
@DerkJanSpeelman Fakta bahwa ada sesuatu yang tidak diizinkan di dalam Scripteks tidak berarti Anda tidak boleh melakukannya dalam Javascript. Mereka berbeda bahasa (meskipun terkait).
lonesomeday

119

Imho solusi terbaik adalah:

fooBar | 0

Ini digunakan dalam asm.js untuk memaksa tipe integer.


Salah satu yang tercepat; +1.
Qix - MONICA DISALAHKAN

3
Bagus Anda juga bisa menggunakan "Boolean ^ 0". ATAU atau XOR berfungsi.
F8ER

Ini tidak akan mengembalikan 1integer kan jika fooBar tidak?
ESR

58

Saya lebih suka menggunakan fungsi Angka . Dibutuhkan objek dan mengubahnya menjadi angka.

Contoh:

var myFalseBool = false;
var myTrueBool = true;

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

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

Anda dapat mengujinya di jsFiddle .


3
Ini adalah jawaban terbaik sejauh ini. Di bagian bawah tentu saja. Hanya "dibutuhkan objek" tidak benar.
Rudie

2
Tautan ke mdn jauh lebih baik daripada w3schools (eeek!): Developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Olivvv

Saya pikir ini adalah cara terbaik karena mudah dibaca dan mengungkap niat.
Sam

3
Itu juga yang paling lambat.
Qix - MONICA DISALAHKAN

45

Saya membuat perbandingan JSperf dari semua jawaban yang disarankan.

TL; DR - opsi terbaik untuk semua browser saat ini adalah:

val | 0;

.

Memperbarui:

Sepertinya hari-hari ini mereka semua sangat identik, kecuali bahwa Number()fungsinya paling lambat, sedangkan yang terbaik val === true ? 1 : 0;.


2
Menariknya, ternary sekarang tercepat di Chrome 64.0.3282 di macOS 10.13.3.
2540625

Itu akan menjadi pilihan tercepat, pada saat itu. Itu berbeda dari itu menjadi pilihan terbaik.
mikemaccana

41

Cara yang diketik untuk melakukan ini adalah:

Number(true) // 1
Number(false) // 0

2
Akhirnya beberapa jawaban yang layak. Terima kasih.
Erik Campobadal

30

Saya baru saja menemukan jalan pintas ini hari ini.

~~ (benar)

~~ (salah)

Orang yang jauh lebih pintar daripada yang bisa saya jelaskan:

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


2
Menarik. Saya belajar sesuatu yang baru hari ini. Saya tidak akan menggunakan teknik ini dalam proyek apa pun, karena potensinya untuk membingungkan masa depan-saya atau rekan satu tim.
nicholaides

1
hacky js adalah favorit saya. serius, +1
Todd

16

Ketika JavaScript mengharapkan nilai angka tetapi menerima boolean sebagai gantinya itu mengubah boolean itu menjadi angka: true dan false dikonversi menjadi masing-masing 1 dan 0. Jadi Anda bisa memanfaatkan ini;

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

Bacaan lebih lanjut Jenis Konversi Bab 3.8 dari Definitive Guide to Javascript.


13

+Operator unary akan menangani hal ini:

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

Anda tentu saja ingin memeriksa kewarasan di server sebelum menyimpannya, jadi itu mungkin tempat yang lebih masuk akal untuk melakukan ini.


Saya telah mengubah komentar menjadi ===, karena true == 1benar bahkan tanpa Anda "konversi eksplisit :-) true === 1sebaliknya itu salah.
xanatos

13

Saya hanya berurusan dengan masalah ini dalam beberapa kode yang saya tulis. Solusi saya adalah menggunakan bitwise dan.

var j = bool & 1;

Cara yang lebih cepat untuk menangani masalah yang konstan adalah dengan membuat fungsi. Ini lebih mudah dibaca oleh orang lain, lebih baik untuk memahami pada tahap pemeliharaan, dan menghilangkan potensi untuk menulis sesuatu yang salah.

function toInt( val ) {
    return val & 1;
}

var j = toInt(bool);

Sunting - 10 September 2014

Tidak ada konversi yang menggunakan operator ternary yang identik dengan operator lebih cepat di Chrome karena alasan tertentu. Tidak masuk akal mengapa itu lebih cepat, tapi saya kira itu semacam optimasi tingkat rendah yang masuk akal di suatu tempat di sepanjang jalan.

var j = boolValue === true ? 1 : 0;

Uji sendiri: http://jsperf.com/boolean-int-conversion/2

Di FireFox dan Internet Explorer, menggunakan versi yang saya posting umumnya lebih cepat.

Sunting - 14 Juli 2017

Oke, saya tidak akan memberi tahu Anda mana yang harus atau tidak harus Anda gunakan. Setiap browser yang aneh telah naik turun dalam seberapa cepat mereka dapat melakukan operasi dengan masing-masing metode. Chrome pada satu titik sebenarnya memiliki versi bitwise & melakukan lebih baik daripada yang lain, tapi kemudian tiba-tiba jauh lebih buruk. Saya tidak tahu apa yang mereka lakukan, jadi saya akan menyerahkannya pada siapa yang peduli. Jarang ada alasan untuk peduli tentang seberapa cepat operasi seperti ini dilakukan. Bahkan di ponsel, ini bukan operasi apa-apa.

Juga, inilah metode yang lebih baru untuk menambahkan prototipe 'toInt' yang tidak dapat ditimpa.

Object.defineProperty(Boolean.prototype, "toInt", { value: function()
{
    return this & 1;
}});

Saya punya dua downvotes untuk posting ini. Mengapa Anda tidak menjelaskan mengapa Anda menurunkannya. Kalau tidak, itu hanya downvote tanpa pembenaran.
Nicholas R. Grant

1
99 kali hasil jsperf hanya membawa Anda ke jalur optimasi prematur, mengoptimalkan nanodetik dari perulangan ketika Anda harus fokus pada pernyataan SQL yang jelek sebagai gantinya. terima kasih telah menyediakan beberapa cara berbeda untuk mendekati ini
RozzA

Apa pernyataan SQL? Tidak ada satu pun permintaan di sini. Jika Anda merujuk ke JSPerf, saya menautkan itu dari tes orang lain. Itu bukan milikku. Sejujurnya saya tidak peduli dengan aspek kinerja karena ini bukan operasi. Saya menciptakan bahasa saya sendiri yang fungsinya hampir sama dengan JS dan saya ingat bahwa casting ke int adalah operasi yang sangat cepat. Pendakian rantai prototipe tidak. Itulah sebabnya saya masih merekomendasikan cara pertama saya melakukannya, dengan fungsi sederhana yang dapat digarisbawahi oleh kompiler.
Nicholas R. Grant

hal SQL 'adalah generalisasi. terima kasih atas wawasannya
RozzA

9

Anda juga dapat menambahkan 0, menggunakan operator shift atau xor:

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

Ini memiliki kecepatan yang sama dengan yang dari jawaban yang lain.


6

Dalam konteks saya, Bereaksi Asli di mana saya mendapatkan nilai opacity dari boolean, cara termudah: Gunakan operator unary +.

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

Ini mengubah boolean menjadi angka;

style={ opacity: +!isFirstStep() }

4

Anda bisa melakukan ini dengan hanya memperpanjang prototipe boolean

Boolean.prototype.intval = function(){return ~~this}

Tidak terlalu mudah untuk memahami apa yang terjadi di sana sehingga versi alternatifnya

Boolean.prototype.intval = function(){return (this == true)?1:0}

setelah melakukan yang dapat Anda lakukan hal-hal seperti

document.write(true.intval());

Ketika saya menggunakan booleans untuk menyimpan kondisi, saya sering mengonversinya ke bitfields dalam hal ini saya akhirnya menggunakan versi lanjutan dari fungsi prototipe

Boolean.prototype.intval = function(places)
{
 places = ('undefined' == typeof(places))?0:places; 
 return (~~this) << places
}

yang dapat Anda lakukan

document.write(true.intval(2))

yang menghasilkan 4 sebagai outputnya.




1

Saya telah menguji semua contoh ini, saya melakukan benchmark, dan akhirnya saya sarankan Anda memilih yang lebih pendek, itu tidak mempengaruhi kinerja.

Dijalankan di server 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")

Hasil

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

jika Anda ingin integer x perubahan nilai jika 1 ke 0 dan jika 0 ke 1 Anda dapat menggunakan (x + 1)% 2

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.