我有一个存储false
或true
的变量,但我分别需要0
或1
。我怎么能这样做?
答案 0 :(得分:375)
使用unary +
operator,将其操作数转换为数字。
+ true; // 1
+ false; // 0
当然,请注意,您仍应该清理服务器端的数据,因为无论客户端代码说什么,用户都可以向服务器发送任何数据。
答案 1 :(得分:285)
Javascript有一个你可以使用的三元运算符:
var i = result ? 1 : 0;
答案 2 :(得分:97)
Imho最好的解决方案是:
fooBar | 0
这在asm.js中用于强制整数类型。
答案 3 :(得分:46)
我更喜欢使用Number function。它需要一个对象并将其转换为数字 例如:
var myFalseBool = false;
var myTrueBool = true;
var myFalseInt = Number(myFalseBool);
console.log(myFalseInt == 0);
var myTrueInt = Number(myTrueBool);
console.log(myTrueInt == 1);
或者在jsFiddle中运行。
答案 4 :(得分:36)
我对所有建议的答案进行了JSperf比较。
TL; DR - 所有当前浏览器的最佳选择是:
val | 0;
<强>更新强>
似乎这几天它们都完全相同,只是Number()
函数最慢,而最好val === true ? 1 : 0;
。
答案 5 :(得分:31)
执行此操作的键入方式是:
Number(true) // 1
Number(false) // 0
答案 6 :(得分:26)
答案 7 :(得分:15)
当JavaScript期望数值但接收到布尔值时,它会将该布尔值转换为数字:true和false分别转换为1和0。所以你可以利用这个;
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
进一步阅读类型转换Javascript权威指南第3.8章。
答案 8 :(得分:12)
我刚刚在编写的一些代码中处理这个问题。我的解决方案是使用按位和。
var j = bool & 1;
处理常量问题的更快方法是创建一个函数。它更容易被其他人阅读,更好地在维护阶段理解,并摆脱写错的可能性。
function toInt( val ) {
return val & 1;
}
var j = toInt(bool);
编辑 - 2014年9月10日
由于某些原因,使用与运营商相同的三元运营商进行转换的速度较快。对于为什么速度更快没有任何意义,但我认为它是某种低级优化,在某个地方有意义。
var j = boolValue === true ? 1 : 0;
自己测试:http://jsperf.com/boolean-int-conversion/2
在FireFox和Internet Explorer中,使用我发布的版本通常更快。
编辑 - 2017年7月14日
好的,我不打算告诉你应该或不应该使用哪一个。每个疯狂的浏览器一直在上下起伏,他们用各种方法进行操作的速度有多快。 Chrome在某一点实际上是按位&amp;版本做得比其他版本好,但后来突然变得更糟。我不知道他们在做什么,所以我只想把它留在谁在意。几乎没有理由关心这样的操作有多快。即使在移动设备上也没什么可操作的。
此外,这是添加“toInt”原型的新方法,无法覆盖。
Object.defineProperty(Boolean.prototype, "toInt", { value: function()
{
return this & 1;
}});
答案 9 :(得分:11)
一元+
运算符将处理此问题:
var test = true;
// +test === 1
test = false;
// +test === 0
在存储它之前,您自然希望在服务器上进行完整性检查,因此无论如何这可能是一个更明智的地方。
答案 10 :(得分:9)
您还可以添加0,使用移位运算符或xor:
val + 0;
val ^ 0;
val >> 0;
val >>> 0;
val << 0;
这些速度与其他答案的速度相似。
答案 11 :(得分:5)
Number
构造函数,一元 +
;一直使用简单的 if
;如果您的项目中的基准以这种方式做得更好,则采用 bool | 0
或 1 * bool
。这是一个很老的问题,有很多有效的答案。我注意到这里的所有基准都是无关紧要的——没有一个考虑到 branch prediction。此外,如今,JS 引擎不再简单地解释代码,而是将其 JIT compile 转换为本地机器代码并在执行之前对其进行优化。这意味着,除了分支预测之外,编译器甚至可以用它们的最终值替换表达式。
现在,这两个因素如何影响布尔到整数转换的性能?让我们一探究竟吧!在我们进入基准测试之前,了解我们的基准测试很重要。对于转换,我们使用以下七种转换方法:
Number(bool)
bool ? 1 : 0
+
:+bool
bool | 0
bool & 1
~~bool
bool * 1
“转换”表示将 false
转换为 0
,将 true
转换为 1
1。每种转换方法运行 100000 次,测量操作数/毫秒。在下表中,转换方法将根据其结果进行分组。结果来自我的机器,它的 CPU 为 AMD Ryzen 7 4800HS。
第一个 benchmark 转换常量 true
:
方法 | Edge/Chromium (V8) | Firefox (Spidermonkey) |
---|---|---|
Number(bool) |
83103 | 1088 |
bool ? 1 : 0 |
83073 | 7732 |
+bool |
83372 | 1043 |
bool | 0 |
83479 | 9344 |
bool & 1 |
83242 | 9354 |
~~bool |
83293 | 9316 |
bool * 1 |
83504 | 9316 |
有趣! V8 显示了一些巨大的数字,它们都大致相同! Spidermonkey 并没有真正发光,但我们可以看到按位和乘法技巧是第一位的,如果第二位是三元。什么是外卖? Chrome 浏览器设法用简单的值 1
替换了我们的转化。这种优化将发生在我们可以将布尔值替换为常量值的地方。
以上不是我们在实际项目中会遇到的情况。所以让我们改变我们的变量:bool 现在是 Math.random() < 0.5
。这会产生 50% 的机会 true
,50% 的 false
。我们的结果会改变吗?让我们运行这个 benchmark 来看看。
方法 | Edge/Chromium (V8) | Firefox (Spidermonkey) |
---|---|---|
Number(bool) |
2405 | 662 |
bool ? 1 : 0 |
1482 | 1580 |
+bool |
2386 | 673 |
bool | 0 |
2391 | 2499 |
bool & 1 |
2409 | 2513 |
~~bool |
2341 | 2493 |
bool * 1 |
2398 | 2518 |
现在的结果更加一致。我们看到三元 if、bitwise 和乘法方法的数字相似,但 Number
构造函数和一元 +
在 V8 上表现更好。我们可以从数字推测 V8 用它用于按位技巧的任何指令替换它们,但在 Spidermonkey 中,这些函数完成了所有工作。
我们还没有解决我们上面提到的一个因素:分支预测。让我们将这个 benchmark 中的布尔变量更改为 Math.random() < 0.01
,这意味着 1% true
, 99% false
。
方法 | Edge/Chromium (V8) | Firefox (Spidermonkey) |
---|---|---|
Number(bool) |
2364 | 865 |
bool ? 1 : 0 |
2352 | 2390 |
+bool |
2447 | 777 |
bool | 0 |
2421 | 2513 |
bool & 1 |
2400 | 2509 |
~~bool |
2446 | 2501 |
bool * 1 |
2421 | 2497 |
出乎意料?预期的?我会说后者,因为在这种情况下,分支预测几乎在所有情况下都是成功的,考虑到三元 if 和按位黑客之间的微小差异。其他结果都一样,这里就不多说了。
这项努力让我们回到了最初的问题:如何在 Javascript 中将 bool 转换为 int?以下是我的建议:
Number(bool)
和 +bool
。这 2 种方法在幕后做了很多工作,即使 Chrome 设法在我们的基准测试中对其进行了优化,Firefox 却没有,而且在某些情况下,编译器可能不会完成这些优化。除此之外,并不是每个人都在使用 Chrome!我还是得忍受,不是吗?...if (bool)
而不是那个丑陋的三元!我希望 Javascript 拥有 Rust 或 Python 所拥有的...if
导致性能不佳 - 如果是这种情况,请随时进入 branchless programming!但是不要在那个兔子洞里钻得太深,相信我,没有人会从 -1 * (a < b) + 1 * (a > b)
之类的东西中受益。我将永远感谢您阅读到最后——这是我第一个更长、更重要的 StackOverflow 答案,如果它对我有帮助和洞察力,它对我来说意味着整个世界。如果您发现任何错误,请随时纠正我!
答案 12 :(得分:4)
你可以通过简单地扩展布尔原型
来做到这一点Boolean.prototype.intval = function(){return ~~this}
理解那里发生的事情并不容易,所以替代版本将是
Boolean.prototype.intval = function(){return (this == true)?1:0}
完成了你可以做的事情,比如
document.write(true.intval());
当我使用布尔值存储条件时,我经常将它们转换为位域,在这种情况下,我最终使用原型函数的扩展版本
Boolean.prototype.intval = function(places)
{
places = ('undefined' == typeof(places))?0:places;
return (~~this) << places
}
你可以做什么
document.write(true.intval(2))
产生4作为输出。
答案 13 :(得分:4)
+!!
允许您将此变量应用于变量undefined
:
+!!undefined // 0
+!!false // 0
+!!true // 1
+!!(<boolean expression>) // 1 if it evaluates to true, 0 otherwise
答案 14 :(得分:3)
let integerVariable = booleanVariable * 1;
答案 15 :(得分:2)
在我的上下文中,React Native是我从布尔中获取不透明度值的最简单方法:使用一元+运算符。
+ true; // 1
+ false; // 0
这会将布尔值转换为数字;
style={ opacity: +!isFirstStep() }
答案 16 :(得分:0)
尝试
val*1
let t=true;
let f=false;
console.log(t*1);
console.log(f*1)
答案 17 :(得分:0)
如果要让整数x值在1到0和0到1之间变化 您可以使用 (x +1)%2
答案 18 :(得分:-1)
我已经测试了所有这些示例,做了基准测试,最后我建议您选择较短的示例,因为它不会影响性能。
在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")
结果
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