Convertir le résultat booléen en nombre / entier


276

J'ai une variable qui stocke falseou true, mais j'ai besoin de 0ou à la 1place, respectivement. Comment puis-je faire ceci?


8
Voici une comparaison des performances de certaines des techniques fournies: jsperf.com/conversion-from-boolean-to-number .
Sam

4
Les utilisateurs de Node.JS voudront utiliser bool === true ? 1 : 0, car il est de loin le plus rapide du V8.
Qix - MONICA A ETE BRUTEE

3
ou tout simplementbool ? 1 : 0;
Atrahasis

Réponses:


343

Javascript a un opérateur ternaire que vous pouvez utiliser:

var i = result ? 1 : 0;

7
Meilleure réponse. Pourquoi? Cela fonctionne sur la véracité qui est plus générale et accepte n'importe quel type (chaîne, nombre, etc.). La réponse unaire est en effet intelligente, mais si je lui passe une chaîne, elle revient NaN. Donc, si vous voulez L33T et garantissez l'entrée, allez uraire, sinon il me semble que le test ternaire + véridique est le meilleur.
gdibble

466

Utilisez l' opérateur unaire+ , qui convertit son opérande en nombre.

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

Notez, bien sûr, que vous devez toujours nettoyer les données côté serveur, car un utilisateur peut envoyer des données à votre serveur, quel que soit le code côté client.


50
Bien que cool (je n'y avais jamais pensé), il est incroyablement lent (97% plus lent dans Chrome, pour être exact). Se méfier!
Qix - MONICA A ETE BRUTEE

5
Découvrez cette révision . Number()est encore plus lent.
Qix - MONICA A ÉTÉ BRUÉE

23
Il semble bool === true ? 1 : 0être le plus rapide, avec une seconde de près bool | 0.
Qix - MONICA A ÉTÉ MANQUÉ

1
La multiplication (par exemple 3 * faux) semble si mauvaise, mais cela fonctionne. :) Merci!
mattsoave

1
@DerkJanSpeelman Le fait que quelque chose ne soit pas autorisé dans Typescript ne signifie pas que vous ne devriez pas le faire en Javascript. Ce sont des langues différentes (quoique apparentées).
lonesomeday

119

À mon humble avis, la meilleure solution est:

fooBar | 0

Ceci est utilisé dans asm.js pour forcer le type entier.


L'un des plus rapides; +1.
Qix - MONICA A ÉTÉ MANQUÉ

3
Joli. Vous pouvez également utiliser "Boolean ^ 0". OU ou XOR fonctionne.
F8ER

Cela ne retournera pas un 1entier si fooBar ne l'est pas?
ESR

58

Je préfère utiliser la fonction Number . Il prend un objet et le convertit en nombre.

Exemple:

var myFalseBool = false;
var myTrueBool = true;

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

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

Vous pouvez le tester dans un jsFiddle .


3
C'est de loin la meilleure réponse. Au fond bien sûr. Seul "il faut un objet" n'est pas correct.
Rudie

2
Lien vers mdn est beaucoup mieux que W3Schools (eeek!): Developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
Olivvv

Je pense que c'est le meilleur moyen car il est facile à lire et à révéler l'intention.
Sam

3
C'est aussi le plus lent.
Qix - MONICA A ETE BRUTEE

45

J'ai créé une comparaison JSperf de toutes les réponses suggérées.

TL; DR - la meilleure option pour tous les navigateurs actuels est:

val | 0;

.

Mettre à jour:

Il semble que ces jours-ci, ils sont tous assez identiques, sauf que la Number()fonction est la plus lente, tout en étant la meilleure val === true ? 1 : 0;.


2
Fait intéressant, le ternaire est maintenant le plus rapide dans Chrome 64.0.3282 sur macOS 10.13.3.
2540625

Ce serait l'option la plus rapide à l'époque. C'est différent d'être la meilleure option.
mikemaccana


30

Je viens de tomber sur ce raccourci aujourd'hui.

~~ (vrai)

~~ (faux)

Des gens beaucoup plus intelligents que je ne peux l'expliquer:

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


2
Intéressant. J'ai appris quelque chose de nouveau aujourd'hui. Je n'utiliserai pas cette technique dans aucun projet, cependant, car elle risque de confondre le futur moi ou les coéquipiers.
nicholaides

1
hacky js est mon préféré. au sérieux, +1
Todd

16

Lorsque JavaScript attend une valeur numérique mais reçoit un booléen à la place, il convertit ce booléen en nombre: true et false convertissent respectivement en 1 et 0. Vous pouvez donc en profiter;

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

Lectures complémentaires Conversions de types Chapitre 3.8 du guide définitif de Javascript.


13

L' +opérateur unaire s'en charge:

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

Vous voudrez naturellement vérifier cela sur le serveur avant de le stocker, de sorte que cela pourrait être un endroit plus judicieux de toute façon.


J'ai changé les commentaires en ===, car true == 1c'est vrai même sans la "conversion explicite :-) à la true === 1place est fausse.
xanatos

13

Je faisais juste face à ce problème dans un code que j'écrivais. Ma solution était d'utiliser un bitwise et.

var j = bool & 1;

Un moyen plus rapide de traiter un problème constant serait de créer une fonction. Il est plus lisible par d'autres personnes, mieux à comprendre au stade de la maintenance et élimine le potentiel d'écriture de quelque chose de mal.

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

var j = toInt(bool);

Edit - 10 septembre 2014

Aucune conversion utilisant un opérateur ternaire avec l'opérateur identique à n'est plus rapide dans Chrome pour une raison quelconque. Cela n'a aucun sens pourquoi il est plus rapide, mais je suppose que c'est une sorte d'optimisation de bas niveau qui a du sens quelque part en cours de route.

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

Testez par vous-même: http://jsperf.com/boolean-int-conversion/2

Dans FireFox et Internet Explorer, l'utilisation de la version que j'ai publiée est généralement plus rapide.

Edit - 14 juillet 2017

D'accord, je ne vais pas vous dire lequel vous devez ou ne devez pas utiliser. Chaque navigateur flippant montait et descendait à quelle vitesse ils pouvaient faire l'opération avec chaque méthode. Chrome à un moment donné avait en fait la version au niveau du bit et mieux que les autres, mais c'était soudain bien pire. Je ne sais pas ce qu'ils font, donc je vais juste laisser à qui s'en soucie. Il n'y a rarement aucune raison de se soucier de la vitesse à laquelle une telle opération est effectuée. Même sur mobile, ce n'est rien.

En outre, voici une nouvelle méthode pour ajouter un prototype «toInt» qui ne peut pas être écrasé.

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

J'ai eu deux downvotes pour ce post. Pourquoi n'expliquez-vous pas pourquoi vous avez voté contre. Sinon, c'est juste un downvote sans justification.
Nicholas R. Grant,

1
99 fois les résultats de jsperf vous mènent juste vers le haut du chemin d'optimisation prématuré, optimisant les nanosecondes hors d'une boucle alors que vous devriez vous concentrer sur cette horrible instruction SQL à la place. merci d'avoir fourni différentes façons d'aborder cela
RozzA

Quelle instruction SQL? Il n'y a pas une seule requête ici. Si vous faites référence à JSPerf, je faisais le lien avec le test de quelqu'un d'autre. Ce n'est pas le mien. Honnêtement, je ne me soucie pas de l'aspect performance de cela car c'est une opération rien. J'ai créé mon propre langage qui était presque une fonctionnalité identique à JS et je me souviens que le casting sur int était une opération stupidement rapide. L'escalade des chaînes prototypes ne l'était pas. C'est pourquoi je recommanderais toujours la première façon de le faire, avec une fonction simple qui peut être intégrée par le compilateur.
Nicholas R. Grant du

la chose SQL était une généralisation. merci pour la perspicacité
RozzA

9

Vous pouvez également ajouter 0, utiliser des opérateurs de décalage ou xor:

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

Ceux-ci ont des vitesses similaires à celles des autres réponses.


7

Dans mon contexte, React Native où je reçois la valeur d'opacité du booléen, la manière la plus simple: Utilisez l'opérateur unaire +.

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

Cela convertit le booléen en nombre;

style={ opacity: +!isFirstStep() }

4

Vous pouvez le faire en étendant simplement le prototype booléen

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

Il n'est pas trop facile de comprendre ce qui se passe là-bas, donc une autre version serait

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

ayant fait ce que vous pouvez faire des choses comme

document.write(true.intval());

Lorsque j'utilise des booléens pour stocker des conditions, je les convertis souvent en champs de bits, auquel cas je finis par utiliser une version étendue de la fonction prototype

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

avec lequel vous pouvez faire

document.write(true.intval(2))

qui produit 4 comme sortie.




1

J'ai testé tous ces exemples, j'ai fait un benchmark, et enfin je vous recommande de choisir le plus court, cela n'affecte pas les performances.

Exécutée sur le serveur 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")

Résultat

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

si vous voulez changer la valeur x entière si 1 à 0 et si 0 à 1 vous pouvez utiliser (x + 1)% 2

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.