Converter resultado booleano em número / número inteiro


276

Eu tenho uma variável que armazena falseou true, mas preciso 0ou 1, em vez disso, respectivamente. Como posso fazer isso?


8
Aqui está uma comparação de desempenho de algumas das técnicas fornecidas: jsperf.com/conversion-from-boolean-to-number .
Sam

4
Os usuários do Node.JS vão querer usar bool === true ? 1 : 0, pois é de longe o mais rápido no V8.
Qix - MONICA FOI ERRADA

3
ou apenas #bool ? 1 : 0;
Atrahasis

Respostas:


343

Javascript tem um operador ternário que você pode usar:

var i = result ? 1 : 0;

7
Melhor resposta. Por quê? Isso funciona com veracidade mais geral e aceita qualquer tipo (string, número, etc.). A resposta unária é realmente inteligente, mas se eu passar uma string, ela retorna NaN. Portanto, se você deseja L33T e garante a entrada, seja cauteloso, caso contrário, acho que o teste ternário + verdade é o melhor.
Gdibble

466

Use o operador unário+ , que converte seu operando em um número.

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

Observe, é claro, que você ainda deve limpar os dados no lado do servidor, porque um usuário pode enviar qualquer dado ao seu servidor, independentemente do código do lado do cliente.


50
Embora legal (nunca pensei nisso), é incrivelmente lento (97% mais lento no Chrome, para ser exato). Seja cauteloso!
Qix - MONICA FOI ERRADA

5
Confira esta revisão . Number()é ainda mais lento.
Qix - MONICA FOI ERRADA

23
Parece bool === true ? 1 : 0ser o mais rápido, com um segundo próximo de bool | 0.
Qix - MONICA FOI ERRADA

1
Multiplicar (por exemplo, 3 * falso) parece tão errado, mas funciona. :) Obrigado!
mattsoave

1
@DerkJanSpeelman O fato de algo não ser permitido no Typescript não significa que você não deve fazê-lo em Javascript. São idiomas diferentes (embora relacionados).
Loneomeday

119

A melhor solução é:

fooBar | 0

Isso é usado no asm.js para forçar o tipo inteiro.


Um dos mais rápidos; +1.
Qix - MONICA FOI ERRADA

3
Agradável. Além disso, você pode usar "Boolean ^ 0". OR ou XOR funciona.
F8ER 22/08/16

Isso não retornará um 1número inteiro, se fooBar não estiver?
ESR

58

Eu prefiro usar a função Number . Ele pega um objeto e o converte em um número.

Exemplo:

var myFalseBool = false;
var myTrueBool = true;

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

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

Você pode testá-lo em um jsFiddle .


3
Esta é a melhor resposta de longe. No fundo, é claro. Apenas "é preciso um objeto" não está certo.
Rudie

2
O link para o mdn é muito melhor do que o w3schools (eeek!): Developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/…
Olivvv

Eu acho que esse é o melhor caminho, porque é fácil de ler e revela as intenções.
Sam

3
Também é o mais lento.
Qix - MONICA FOI ERRADA EM

45

Eu criei uma comparação JSperf de todas as respostas sugeridas.

TL; DR - a melhor opção para todos os navegadores atuais é:

val | 0;

.

Atualizar:

Parece que hoje em dia eles são todos idênticos, exceto que a Number()função é a mais lenta e a melhor val === true ? 1 : 0;.


2
Curiosamente, o ternário agora é o mais rápido no Chrome 64.0.3282 no macOS 10.13.3.
2540625

Essa seria a opção mais rápida na época. Isso é diferente de ser a melhor opção.
mikemaccana 27/01

41

A maneira digitada de fazer isso seria:

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

2
Finalmente, uma resposta decente. Obrigado.
Erik Campobadal


16

Quando o JavaScript espera um valor numérico, mas recebe um booleano, ele o converte em um número: true e false convertem em 1 e 0, respectivamente. Então você pode tirar proveito disso;

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

Leitura adicional Conversões de tipo Capítulo 3.8 do Guia definitivo para Javascript.


13

O +operador unário cuidará disso:

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

Naturalmente, você deseja verificar isso com integridade no servidor antes de armazená-lo, para que, de qualquer maneira, seja um local mais sensato para fazer isso.


Eu mudei os comentários para ===, porque true == 1é verdade mesmo sem a "conversão explícita :-), em true === 1vez disso, é falsa.
Xanatos 19/10/11

13

Eu estava lidando com esse problema em algum código que estava escrevendo. Minha solução foi usar um bit a bit e.

var j = bool & 1;

Uma maneira mais rápida de lidar com um problema constante seria criar uma função. É mais legível por outras pessoas, melhor para a compreensão no estágio de manutenção e se livra do potencial de escrever algo errado.

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

var j = toInt(bool);

Editar - 10 de setembro de 2014

Nenhuma conversão usando um operador ternário com o mesmo operador é mais rápida no Chrome por algum motivo. Não faz sentido o porquê de ser mais rápido, mas suponho que seja algum tipo de otimização de baixo nível que faça algum sentido ao longo do caminho.

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

Teste você mesmo: http://jsperf.com/boolean-int-conversion/2

No FireFox e no Internet Explorer, o uso da versão que eu publiquei geralmente é mais rápido.

Editar - 14 de julho de 2017

Ok, não vou dizer qual você deve ou não usar. Todos os navegadores estão subindo e descendo com a rapidez com que podem executar a operação com cada método. O Chrome, em um ponto, na verdade, tinha a versão bit a bit e melhor do que as outras, mas, de repente, ficou muito pior. Não sei o que eles estão fazendo, então vou deixar para quem se importa. Raramente existe motivo para se preocupar com a rapidez com que uma operação como essa é feita. Mesmo no celular, é uma operação do nada.

Além disso, eis um método mais novo para adicionar um protótipo 'toInt' que não pode ser substituído.

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

Eu tive dois votos negativos para este post. Por que você não explica por que votou contra? Caso contrário, é apenas um voto negativo sem justificativa.
Nicholas R. Grant

1
99 vezes os resultados do jsperf apenas o levam ao caminho prematuro da otimização, otimizando nanossegundos de um loop quando você deve se concentrar nessa instrução SQL feia. Obrigado por fornecer algumas maneiras diferentes de abordar esta questão
ROZZA

Qual instrução SQL? Não há uma única consulta aqui. Se você está se referindo ao JSPerf, eu estava vinculando isso do teste de outra pessoa. Não é meu. Sinceramente, não me importo com o aspecto de desempenho disso, pois é uma operação do nada. Criei minha própria linguagem que era quase uma funcionalidade idêntica à JS e lembro que a conversão para int era uma operação estupidamente rápida. Escalar cadeias de protótipos não era. É por isso que eu ainda recomendaria a primeira maneira de fazê-lo, com uma função simples que pode ser incorporada pelo compilador.
Nicholas R. Grant

a coisa do SQL é uma generalização. obrigado pela visão
ROZZA

9

Você também pode adicionar 0, usar operadores shift ou xor:

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

Eles têm velocidades semelhantes às das outras respostas.


6

No meu contexto, React Native, onde estou obtendo o valor de opacidade do booleano, a maneira mais fácil: Use o operador unary +.

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

Isso converte o booleano em número;

style={ opacity: +!isFirstStep() }

4

Você pode fazer isso simplesmente estendendo o protótipo booleano

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

Não é muito fácil entender o que está acontecendo lá; portanto, uma versão alternativa seria

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

tendo feito o que você pode fazer coisas como

document.write(true.intval());

Quando uso booleanos para armazenar condições, costumo convertê-los em campos de bits. Nesse caso, acabo usando uma versão estendida da função prototype

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

com o qual você pode fazer

document.write(true.intval(2))

que produz 4 como sua saída.


4
let integerVariable = booleanVariable * 1;


1

Eu testei todos esses exemplos, fiz uma referência e, finalmente, recomendo que você escolha a mais curta, não afeta o desempenho.

Executado no 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

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.