Ho una variabile che memorizza false
o true
, ma ho bisogno 0
o 1
invece, rispettivamente. Come posso fare questo?
bool === true ? 1 : 0
, poiché è di gran lunga il più veloce in V8.
bool ? 1 : 0;
Ho una variabile che memorizza false
o true
, ma ho bisogno 0
o 1
invece, rispettivamente. Come posso fare questo?
bool === true ? 1 : 0
, poiché è di gran lunga il più veloce in V8.
bool ? 1 : 0;
Risposte:
Javascript ha un operatore ternario che puoi usare:
var i = result ? 1 : 0;
NaN
. Quindi, se vuoi L33T e garantire l'input, vai all'urario, altrimenti pensa che il test ternario + verità sia il migliore.
Utilizzare l' operatore unario+
, che converte il suo operando in un numero.
+ true; // 1
+ false; // 0
Si noti, ovviamente, che è comunque necessario disinfettare i dati sul lato server, poiché un utente può inviare qualsiasi dato al server, indipendentemente da ciò che dice il codice lato client.
Number()
è ancora più lento.
bool === true ? 1 : 0
il più veloce, con un secondo vicino da bool | 0
.
Imho la soluzione migliore è:
fooBar | 0
Questo è usato in asm.js per forzare il tipo intero.
1
numero intero se FooBar non lo è?
Preferisco usare la funzione Numero . Prende un oggetto e lo converte in un numero.
Esempio:
var myFalseBool = false;
var myTrueBool = true;
var myFalseInt = Number(myFalseBool);
console.log(myFalseInt === 0);
var myTrueInt = Number(myTrueBool);
console.log(myTrueInt === 1);
Puoi provarlo in un jsFiddle .
Ho creato un confronto JSperf di tutte le risposte suggerite.
TL; DR: l'opzione migliore per tutti i browser attuali è:
val | 0;
.
Aggiornare:
Sembra che in questi giorni siano tutti abbastanza identici, tranne per il fatto che la Number()
funzione è la più lenta, mentre la migliore è val === true ? 1 : 0;
.
Il modo tipizzato per farlo sarebbe:
Number(true) // 1
Number(false) // 0
Ho appena trovato questa scorciatoia oggi.
~~ (vero)
~~ (false)
Persone molto più intelligenti di quanto io possa spiegare:
Quando JavaScript si aspetta un valore numerico ma riceve un valore booleano invece converte quel valore booleano in un numero: true e false vengono convertiti rispettivamente in 1 e 0. Quindi puoi approfittare di questo;
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
Ulteriori letture Conversioni di tipi Capitolo 3.8 della Guida definitiva a Javascript.
L' +
operatore unario si occuperà di questo:
var test = true;
// +test === 1
test = false;
// +test === 0
Avrai naturalmente bisogno di controllare la sanità mentale sul server prima di archiviarlo, quindi potrebbe essere comunque un posto più ragionevole per farlo.
===
, perché true == 1
è vero anche senza la "conversione esplicita :-) true === 1
invece è falso.
Stavo solo affrontando questo problema in qualche codice che stavo scrivendo. La mia soluzione era di usare un bit per bit e.
var j = bool & 1;
Un modo più rapido per affrontare un problema costante sarebbe quello di creare una funzione. È più leggibile da altre persone, meglio per la comprensione in fase di manutenzione e elimina il potenziale per scrivere qualcosa di sbagliato.
function toInt( val ) {
return val & 1;
}
var j = toInt(bool);
Modifica - 10 settembre 2014
Nessuna conversione tramite Chrome con un operatore ternario identico all'operatore è più veloce in Chrome per qualche motivo. Non ha senso il motivo per cui è più veloce, ma suppongo che sia una sorta di ottimizzazione di basso livello che ha senso da qualche parte lungo la strada.
var j = boolValue === true ? 1 : 0;
Prova tu stesso: http://jsperf.com/boolean-int-conversion/2
In FireFox e Internet Explorer, l'utilizzo della versione che ho pubblicato è generalmente più veloce.
Modifica - 14 luglio 2017
Okay, non ti dirò quale dovresti o non dovresti usare. Ogni browser impazzito è andato su e giù in quanto velocemente può fare l'operazione con ogni metodo. Chrome a un certo punto aveva effettivamente la versione bit per bit e migliore degli altri, ma improvvisamente è andata molto peggio. Non so cosa stiano facendo, quindi lo lascerò a chi se ne frega. Raramente ci sono motivi per preoccuparsi di quanto velocemente viene eseguita un'operazione come questa. Anche sul cellulare è un'operazione nulla.
Inoltre, ecco un nuovo metodo per aggiungere un prototipo 'toInt' che non può essere sovrascritto.
Object.defineProperty(Boolean.prototype, "toInt", { value: function()
{
return this & 1;
}});
Nel mio contesto, React Native, dove sto ottenendo il valore di opacità dal valore booleano, il modo più semplice: utilizzare unario + operatore.
+ true; // 1
+ false; // 0
Questo converte il valore booleano in numero;
style={ opacity: +!isFirstStep() }
Puoi farlo semplicemente estendendo il prototipo booleano
Boolean.prototype.intval = function(){return ~~this}
Non è troppo facile capire cosa sta succedendo lì, quindi sarebbe una versione alternativa
Boolean.prototype.intval = function(){return (this == true)?1:0}
dopo aver fatto ciò che puoi fare cose come
document.write(true.intval());
Quando uso i booleani per memorizzare le condizioni, li converto spesso in bitfield, nel qual caso finisco per usare una versione estesa della funzione prototipo
Boolean.prototype.intval = function(places)
{
places = ('undefined' == typeof(places))?0:places;
return (~~this) << places
}
con cui puoi fare
document.write(true.intval(2))
che produce 4 come output.
Ho testato tutti questi esempi, ho fatto un benchmark e infine ti consiglio di scegliere quello più corto, non influisce sulle prestazioni.
Eseguito nel 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")
Risultato
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
se vuoi che il valore intero x cambi se da 1 a 0 e se da 0 a 1 puoi usare (x + 1)% 2