Boole sonucunu sayı / tamsayıya dönüştür


276

Ben mağazalar bir değişken var falseya true, ama gerek 0yoksa 1bunun yerine, sırasıyla. Bunu nasıl yapabilirim?


8
Sağlanan tekniklerin bazılarının performans karşılaştırması aşağıda verilmiştir: jsperf.com/conversion-from-boolean-to-number .
Sam

4
Node.JS kullanıcıları, bool === true ? 1 : 0V8'in en hızlısı olduğu için kullanmak isteyeceklerdir .
Qix - MONICA

3
or justbool ? 1 : 0;
Atrahasis

Yanıtlar:


343

Javascript'te kullanabileceğiniz üçlü bir operatör vardır:

var i = result ? 1 : 0;

7
En iyi cevap. Neden? Bu, daha genel olan ve herhangi bir türü (dize, sayı vb.) Kabul eden doğruluk üzerinde çalışır. Tekli cevap gerçekten zekidir, ancak bir dize geçersem döner NaN. Eğer L33T istiyorsanız ve girişi garanti ederseniz, çirkin olun, aksi takdirde üçlü + doğruluk testi en iyisidir.
gdibble

465

İşleneni+ sayıya dönüştüren tekli işleci kullanın .

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

Tabii ki, yine de sunucu tarafındaki verileri dezenfekte etmeniz gerektiğini unutmayın, çünkü bir kullanıcı istemci tarafındaki kod ne olursa olsun sunucunuza herhangi bir veri gönderebilir.


50
Serin olsa da (bunu hiç düşünmemiştim), inanılmaz derecede yavaş (Chrome'da% 97 daha yavaş, kesin olarak). Dikkatli olmak!
Qix - MONICA

5
Check out Bu revizyon . Number()daha yavaştır.
Qix - MONICA

23
Görünen bool === true ? 1 : 0en hızlı, yakın bir saniye ile bool | 0.
Qix - MONICA

1
Çarpma (örneğin 3 * yanlış) çok yanlış geliyor, ama işe yarıyor. :) Teşekkürler!
mattsoave

1
@DerkJanSpeelman Typescript'te bir şeye izin verilmemesi, Javascript'te yapmamanız gerektiği anlamına gelmez. Farklı (birbirleriyle ilişkili olsa da) dillerdir.
lonesomeday

119

En iyi çözüm:

fooBar | 0

Bu, asm.js'de tamsayı türünü zorlamak için kullanılır.


En hızlılarından biri; +1.
Qix - MONICA

3
Güzel bir. Ayrıca "Boolean ^ 0" kullanabilirsiniz. VEYA veya XOR çalışır.
F8ER

1Eğer fooBar değilse bu bir tamsayı döndürmez ?
ESR

58

Sayı işlevini kullanmayı tercih ederim . Bir nesneyi alır ve bir sayıya dönüştürür.

Misal:

var myFalseBool = false;
var myTrueBool = true;

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

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

Bir jsFiddle'da test edebilirsiniz .


3
Bu en iyi cevap. Tabii ki dibinde. Sadece "bir nesne alır" doğru değildir.
Rudie


Bunun en iyi yol olduğunu düşünüyorum çünkü okunması kolay ve niyeti açığa çıkarıyor.
Sam

3
Aynı zamanda en yavaş olanıdır.
Qix - MONICA

45

Önerilen tüm cevapların bir JSperf karşılaştırmasını oluşturdum .

TL; DR - mevcut tüm tarayıcılar için en iyi seçenek:

val | 0;

.

Güncelleme:

Görünüşe göre bu günlerin hepsi oldukça özdeş, tek fark Number()fonksiyonun en yavaş olması ve en iyi varlık olması val === true ? 1 : 0;.


2
İlginçtir ki, üçlü macOS 10.13.3'te Chrome 64.0.3282'de en hızlı.
2540625

O zaman en hızlı seçenek bu olurdu. Bu en iyi seçenek olmaktan farklıdır.
mikemaccana



16

JavaScript bir sayı değeri beklerken, bunun yerine bir boole alırsa, bu boole değerini bir sayıya dönüştürür: true ve false sırasıyla 1 ve 0'a dönüştürür. Böylece bundan faydalanabilirsiniz;

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

Daha fazla okuma Tür Dönüşümleri Javascript için Kesin Kılavuz Bölüm 3.8.


13

Tekli +operatör bununla ilgilenir:

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

Doğal olarak bunu saklamadan önce sunucuda akıl sağlığı kontrol etmek isteyeceksiniz, bu yüzden yine de bunu yapmak için daha mantıklı bir yer olabilir.


Ben yorumlarını değiştirdim ===, çünkü true == 1doğru olsa bile "açık dönüşüm :-) true === 1yerine yanlış.
xanatos

13

Yazdığım bazı kodlarda sadece bu konuyla uğraşıyordum. Benim çözümüm bitsel ve kullanmaktı.

var j = bool & 1;

Sürekli bir sorunla başa çıkmanın daha hızlı bir yolu bir işlev oluşturmak olacaktır. Diğer insanlar tarafından daha okunabilir, bakım aşamasında anlamak için daha iyi ve yanlış bir şey yazma potansiyelinden kurtulur.

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

var j = toInt(bool);

Düzenle - 10 Eylül 2014

Chrome'da operatörle aynı üçlü bir operatör kullanarak dönüşüm yapılmaması, bazı nedenlerden dolayı Chrome'da daha hızlı değildir. Neden daha hızlı olduğu konusunda hiçbir anlam ifade etmiyor, ancak sanırım yol boyunca bir yerde mantıklı olan bir çeşit düşük seviye optimizasyon.

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

Kendiniz test edin: http://jsperf.com/boolean-int-conversion/2

FireFox ve Internet Explorer'da, gönderdiğim sürümü kullanmak genellikle daha hızlıdır.

Düzenle - 14 Temmuz 2017

Tamam, size hangisini kullanmanız gerektiğini söylemeyeceğim. Her korkutucu tarayıcı, her yöntemle işlemi ne kadar hızlı yapabildiklerinde yukarı ve aşağı gidiyor. Bir noktada Chrome aslında bitwise ve sürümün diğerlerinden daha iyi performans gösterdi, ancak sonra aniden çok daha kötüydü. Ne yaptıklarını bilmiyorum, bu yüzden onu kimin umurunda bırakacağım. Böyle bir işlemin ne kadar hızlı yapıldığını önemsemek için nadiren herhangi bir neden vardır. Mobil cihazlarda bile bu hiçbir şey işlemez.

Ayrıca, üzerine yazılamayacak bir 'toInt' prototipi eklemek için daha yeni bir yöntem var.

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

Bu gönderi için iki ayrı oy kullandım. Neden bunu neden düşürdüğünü açıklamıyorsun. Aksi takdirde, gerekçe olmadan sadece bir aşağı oy.
Nicholas R. Grant

1
99 kez jsperf sonuçları sadece erken optimizasyon yolu yol açar, bunun yerine bu çirkin SQL deyimine odaklanmak gerektiğinde nanosaniye bir döngü kapalı optimize. Bu yaklaşıma birkaç farklı yol sağladığınız için teşekkür ederiz
RozzA

Hangi SQL ifadesi? Burada tek bir sorgu yok. JSPerf'den bahsediyorsanız, bunu başkasının testinden bağlıyordum. Bu benim değil. Dürüst olmak gerekirse bunun performans yönünü umursamıyorum, çünkü bu bir işlem değil. JS ile neredeyse aynı işlevlere sahip kendi dilimi oluşturdum ve int'e çevirmenin aptalca hızlı bir işlem olduğunu hatırlıyorum. Prototip zincirlerine tırmanmak değildi. Bu yüzden derleyici tarafından inline edilebilen basit bir işlevle, ilk yaptığım yolu tavsiye ederim.
Nicholas R. Grant

SQL şey bir genelleme twas. anlayışınız için teşekkürler
RozzA

9

Ayrıca 0 ekleyebilir, vardiya operatörlerini veya xor kullanabilirsiniz:

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

Bunlar diğerlerinin cevaplarına benzer hızlara sahiptir.


6

Bağlamımda, en kolay yol olan boole'den opaklık değeri elde ettiğim React Native: Tekli + işleci kullanın.

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

Bu, boole sayısını sayıya dönüştürür;

style={ opacity: +!isFirstStep() }

4

Bunu sadece boole prototipini genişleterek yapabilirsiniz

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

Orada neler olduğunu anlamak çok kolay değil, bu yüzden alternatif bir sürüm

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

sizin gibi şeyler yapabileceğiniz

document.write(true.intval());

Koşulları saklamak için booleans kullandığımda genellikle bit alanlarına dönüştürürüm, bu durumda prototip işlevinin genişletilmiş bir sürümünü kullanırım

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

hangi ile yapabilirsin

document.write(true.intval(2))

çıktı olarak 4 üretir.




1

Tüm bu örnekleri test ettim, bir kıyaslama yaptım ve son olarak daha kısa olanı seçmenizi öneririm, bu performansı etkilemez.

Ubuntu sunucusunda çalıştırıldı 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")

Sonuç

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

1'den 0'a tamsayı x değeri değiştirmek istiyorsanız ve 0'dan 1'e kadar (x + 1)% 2 kullanabilirsiniz

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.