Convierta el resultado booleano en número / entero

276

Tengo una variable que almacena falseo true, pero necesito 0o en su 1lugar, respectivamente. ¿Cómo puedo hacer esto?

hd.
fuente
8
Aquí hay una comparación de rendimiento de algunas de las técnicas proporcionadas: jsperf.com/conversion-from-boolean-to-number .
Sam
44
Los usuarios de Node.JS querrán usar bool === true ? 1 : 0, ya que es, con mucho, el más rápido en V8.
Qix - MONICA FUE MALTRATADA el
3
o simplementebool ? 1 : 0;
Atrahasis

Respuestas:

343

Javascript tiene un operador ternario que puede usar:

var i = result ? 1 : 0;
Andy Rose
fuente
77
La mejor respuesta. ¿Por qué? Esto funciona en la veracidad, que es más general y acepta cualquier tipo (cadena, número, etc.). La respuesta unaria es realmente inteligente, pero si le paso una cadena, devuelve NaN. Entonces, si desea L33T y garantiza la entrada, vaya al urinario, de lo contrario, creo que la prueba ternaria + verdadera es la mejor.
gdibble
466

Use el operador unario+ , que convierte su operando en un número.

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

Tenga en cuenta, por supuesto, que aún debe desinfectar los datos en el lado del servidor, porque un usuario puede enviar cualquier dato a su servidor, sin importar lo que diga el código del lado del cliente.

solitario
fuente
50
Aunque genial (nunca había pensado en esto), es increíblemente lento (97% más lento en Chrome, para ser exactos). ¡Sé cauteloso!
Qix - MONICA FUE MALTRATADA el
55
Mira esta revisión . Number()Es aún más lento.
Qix - MONICA FUE MALTRATADA el
23
Parece que bool === true ? 1 : 0es el más rápido, con un segundo cercano desde bool | 0.
Qix - MONICA FUE MALTRATADA el
1
Multiplicar (por ejemplo, 3 * falso) se siente muy mal, pero funciona. :) ¡Gracias!
mattsoave
1
@DerkJanSpeelman El hecho de que algo no esté permitido en Typecript no significa que no debas hacerlo en Javascript. Son idiomas diferentes (aunque relacionados).
solitario el
119

En mi opinión, la mejor solución es:

fooBar | 0

Esto se usa en asm.js para forzar el tipo entero.

kralyk
fuente
Uno de los mas rapidos; +1.
Qix - MONICA FUE MALTRATADA el
3
Buena esa. También podría usar "Boolean ^ 0". O o XOR funciona.
F8ER
Esto no devolverá un 1número entero, ¿no es así si fooBar no lo es?
ESR
58

Prefiero usar la función Número . Toma un objeto y lo convierte en un número.

Ejemplo:

var myFalseBool = false;
var myTrueBool = true;

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

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

Puedes probarlo en un jsFiddle .

René
fuente
3
Esta es la mejor respuesta con diferencia. En el fondo, por supuesto. Solo "se necesita un objeto" no está bien.
Rudie
2
El enlace a mdn es mucho mejor que w3schools (¡eeek!): Developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Olivvv
Creo que esta es la mejor manera porque es fácil de leer y revela la intención.
Sam
3
También es el más lento.
Qix - MONICA FUE MALTRATADA el
45

Creé una comparación JSperf de todas las respuestas sugeridas.

TL; DR: la mejor opción para todos los navegadores actuales es:

val | 0;

.

Actualizar:

Parece que en estos días todos son bastante idénticos, excepto que la Number()función es la más lenta y la mejor val === true ? 1 : 0;.

Gal Talmor
fuente
2
Curiosamente, el ternario ahora es más rápido en Chrome 64.0.3282 en macOS 10.13.3.
2540625
Esa sería la opción más rápida, en ese momento. Eso es distinto de ser la mejor opción.
mikemaccana
41

La forma mecanografiada de hacer esto sería:

Number(true) // 1
Number(false) // 0
Philip
fuente
2
Finalmente alguna respuesta decente. Gracias.
Erik Campobadal
30

Acabo de encontrar este atajo hoy.

~~ (cierto)

~~ (falso)

Gente mucho más inteligente de lo que puedo explicar:

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

tonyjcamp
fuente
2
Interesante. Aprendí algo nuevo hoy. Sin embargo, no usaré esta técnica en ningún proyecto, porque es posible confundir a futuros compañeros de equipo.
Nicholaides
1
Hacky JS es mi favorito. en serio, +1
Todd
16

Cuando JavaScript espera un valor numérico pero recibe un valor booleano, convierte ese valor booleano en un número: verdadero y falso se convierten en 1 y 0 respectivamente. Entonces puedes aprovechar esto;

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

Lecturas adicionales Conversiones de tipos Capítulo 3.8 de La Guía definitiva de Javascript.

Charlie Lynch
fuente
13

El +operador unario se encargará de esto:

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

Naturalmente, querrá comprobar esto en el servidor antes de almacenarlo, por lo que de todos modos podría ser un lugar más sensato para hacerlo.

Gustav Barkefors
fuente
He cambiado a los comentarios ===, porque true == 1es cierto incluso Withou la "conversión explícita :-) true === 1lugar es falso.
Xánatos
13

Estaba lidiando con este problema en algún código que estaba escribiendo. Mi solución fue usar un bit a bit y.

var j = bool & 1;

Una forma más rápida de lidiar con un problema constante sería crear una función. Es más legible para otras personas, mejor para comprender en la etapa de mantenimiento, y elimina el potencial de escribir algo mal.

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

var j = toInt(bool);

Editar - 10 de septiembre de 2014

Ninguna conversión usando un operador ternario con el operador idéntico es más rápido en Chrome por alguna razón. No tiene sentido por qué es más rápido, pero supongo que es una especie de optimización de bajo nivel que tiene sentido en algún lugar del camino.

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

Prueba por ti mismo: http://jsperf.com/boolean-int-conversion/2

En Firefox e Internet Explorer, usar la versión que publiqué es más rápido en general.

Editar - 14 de julio de 2017

De acuerdo, no voy a decirte cuál deberías usar o no. Cada maldito navegador ha estado subiendo y bajando en la rapidez con que pueden hacer la operación con cada método. Chrome en un punto en realidad tenía la versión bit a bit y mejor que las otras, pero de repente fue mucho peor. No sé lo que están haciendo, así que lo dejaré a quién le importa. Rara vez hay alguna razón para preocuparse por la rapidez con que se realiza una operación como esta. Incluso en dispositivos móviles es una operación de nada.

Además, aquí hay un método más nuevo para agregar un prototipo 'toInt' que no se puede sobrescribir.

Object.defineProperty(Boolean.prototype, "toInt", { value: function()
{
    return this & 1;
}});
Nicholas R. Grant
fuente
He tenido dos votos negativos para esta publicación. ¿Por qué no explicas por qué lo rechazaste? De lo contrario, es solo un voto negativo sin justificación.
Nicholas R. Grant
1
99 veces los resultados de jsperf solo lo llevan a la ruta de optimización prematura, optimizando los nanosegundos en un bucle cuando debería centrarse en esa fea declaración SQL. gracias por proporcionar algunas formas diferentes de abordar esto
RozzA
¿Qué sentencia SQL? No hay una sola consulta aquí. Si te refieres a JSPerf, estaba vinculando eso desde la prueba de otra persona. No es mio. Sinceramente, no me importa el aspecto de rendimiento de esto, ya que es una operación nada. Creé mi propio lenguaje que era casi una funcionalidad idéntica a JS y recuerdo que enviar a int fue una operación estúpidamente rápida. Escalar cadenas prototipo no lo era. Es por eso que aún recomendaría la primera forma en que lo hice, con una función simple que el compilador puede incorporar.
Nicholas R. Grant
Lo de SQL fue una generalización. gracias por la información
RozzA
9

También puede agregar 0, usar operadores de desplazamiento o xor:

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

Estos tienen velocidades similares a las de las otras respuestas.

REMqb
fuente
6

En mi contexto, React Native donde obtengo el valor de opacidad de booleano, la forma más fácil: usar unario + operador.

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

Esto convierte el booleano en número;

style={ opacity: +!isFirstStep() }
Jose Velasco
fuente
4

Podrías hacer esto simplemente extendiendo el prototipo booleano

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

No es demasiado fácil entender lo que está sucediendo allí, por lo que una versión alternativa sería

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

habiendo hecho lo que puedes hacer, como

document.write(true.intval());

Cuando uso booleanos para almacenar condiciones, a menudo los convierto en campos de bits, en cuyo caso termino usando una versión extendida de la función prototipo

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

con lo que puedes hacer

document.write(true.intval(2))

que produce 4 como su salida.

DroidOS
fuente
4
let integerVariable = booleanVariable * 1;
Esger
fuente
1

He probado todos estos ejemplos, hice un punto de referencia, y finalmente le recomiendo que elija el más corto, no afecta el rendimiento.

Ejecutado en el servidor 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")

Resultado

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
DarckBlezzer
fuente
0

si desea un valor entero x cambie si 1 a 0 y si 0 a 1 puede usar (x + 1)% 2

şevket Karayılan
fuente