将布尔结果转换为数字/整数

hd.*_*hd. 243 javascript integer boolean numbers type-conversion

我有一个变量存储falsetrue,但我需要01相反.我怎样才能做到这一点?

lon*_*day 412

使用一元运算+,将其操作数转换为数字.

+ true; // 1
+ false; // 0
Run Code Online (Sandbox Code Playgroud)

当然,请注意,您仍应该清理服务器端的数据,因为无论客户端代码说什么,用户都可以向服务器发送任何数据.

  • 虽然很酷(我从来没有想过这个),它是[**令人难以置信的**慢](http://jsperf.com/boolean-int-conversion/2)(确切地说,在Chrome中慢了97%).警惕! (43认同)
  • 看来`bool ===是真的吗?1:0`是最快的,与`bool |紧密相关 0`. (18认同)
  • 查看[本修订版](http://jsperf.com/boolean-int-conversion/3).`Number()`甚至更慢. (4认同)
  • @DerkJanSpeelman Typescript 中不允许某些操作的事实并不意味着您不应该在 Javascript 中执行此操作。它们是不同的(尽管相关)语言。 (2认同)

And*_*ose 312

Javascript有一个你可以使用的三元运算符:

var i = result ? 1 : 0;
Run Code Online (Sandbox Code Playgroud)

  • 最佳答案.为什么?这适用于更一般的真实性并接受任何类型(字符串,数字等等).一元的答案确实很聪明,但如果我传递一个字符串它会返回"NaN".所以,如果你想要L33T并保证输入,那就去吧,否则最好用三元+ truthy测试. (6认同)
  • 三元解决方案是最快的方法之一。其他解决方案如“+true”或“Number(true)”非常慢。请参阅[基准](https://jsben.ch/dYdis)。 (3认同)

kra*_*lyk 104

Imho最好的解决方案是:

fooBar | 0
Run Code Online (Sandbox Code Playgroud)

这在asm.js中用于强制整数类型.

  • 或者`fooBar&1`. (5认同)
  • 好一个.你也可以使用"Boolean ^ 0".OR或XOR有效. (3认同)
  • 如果 fooBar 不是,这不会返回“1”整数,对吗? (3认同)
  • 打字稿错误:“算术运算的左侧必须是‘any’、‘number’、‘bigint’或枚举类型。” (3认同)
  • 最快的之一;+1。 (2认同)

Ren*_*ené 49

我更喜欢使用Number函数.它需要一个对象并将其转换为数字.
例:

var myFalseBool = false;
var myTrueBool = true;

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

var myTrueInt = Number(myTrueBool);
console.log(myTrueInt == 1);
Run Code Online (Sandbox Code Playgroud)

或者在jsFiddle中运行它.

  • 我认为这是最好的方法,因为它易于阅读和意图揭示。 (3认同)
  • 它也是*最慢的. (3认同)
  • 到目前为止,这是最好的答案。当然在底部。仅“带一个物体”是不对的。 (2认同)
  • 链接到 mdn 比 w3schools(eeek !) 好得多:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number (2认同)

Gal*_*mor 39

我创建了所有建议答案的JSperf比较.

TL; DR - 所有当前浏览器的最佳选择是:

val | 0;
Run Code Online (Sandbox Code Playgroud)

.

更新:

看起来这些日子他们都非常相同,除了Number()功能最慢,而最好的功能val === true ? 1 : 0;.

  • 有趣的是,三元组现在在macOS 10.13.3上的Chrome 64.0.3282中最快。 (2认同)

Phi*_*nci 33

执行此操作的键入方式是:

Number(true) // 1
Number(false) // 0
Run Code Online (Sandbox Code Playgroud)

  • 终于有一个像样的答案了。谢谢。 (2认同)

ton*_*amp 29

我今天刚遇到这条捷径.

~~(真)

~~(假)

人们比我能解释的要聪明得多:

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

  • 有趣.我今天学了些新东西.但是,我不会在任何项目中使用这种技术,因为它可能会混淆未来我或队友. (2认同)

小智 16

当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
Run Code Online (Sandbox Code Playgroud)

进一步阅读类型转换Javascript权威指南的第3.8章.


Nic*_*ant 13

我只是在编写的一些代码中处理这个问题.我的解决方案是使用按位和.

var j = bool & 1;
Run Code Online (Sandbox Code Playgroud)

处理常量问题的更快方法是创建一个函数.它更容易被其他人阅读,更好地在维护阶段理解,并摆脱写错的可能性.

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

var j = toInt(bool);
Run Code Online (Sandbox Code Playgroud)

编辑 - 2014年9月10日

由于某些原因,在Chrome中使用与运算符相同的三元运算符进行转换的速度更快.对于为什么它更快没有任何意义,但我认为它是某种低级优化,在某个地方有意义.

var j = boolValue === true ? 1 : 0;
Run Code Online (Sandbox Code Playgroud)

自己测试:http://jsperf.com/boolean-int-conversion/2

在FireFox和Internet Explorer中,使用我发布的版本通常更快.

编辑 - 2017年7月14日

好的,我不打算告诉你哪一个你应该或不应该使用.每个疯狂的浏览器一直在上下起伏,他们用各种方法进行操作的速度有多快.Chrome在某一点实际上有点和版本比其他更好,但后来它突然变得更糟.我不知道他们在做什么,所以我只想把它留在谁在乎.几乎没有理由关心这样的操作有多快.即使在移动设备上,也没什么可操作的.

此外,这是一个更新的方法,用于添加无法覆盖的'toInt'原型.

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


Gus*_*ors 11

一元运算+符将负责这个:

var test = true;
// +test === 1
test = false;
// +test === 0
Run Code Online (Sandbox Code Playgroud)

在存储它之前,您自然希望在服务器上进行完整性检查,因此无论如何这可能是一个更明智的地方.


小智 9

您还可以添加0,使用shift运算符或xor:

val + 0;
val ^ 0;
val >> 0;
val >>> 0;
val << 0;
Run Code Online (Sandbox Code Playgroud)

它们的速度与其他答案的速度相似.


小智 9

在我的上下文中,我从布尔值获取不透明度值的 React Native,最简单的方法是:使用一元 + 运算符。

+ true; // 1
+ false; // 0
Run Code Online (Sandbox Code Playgroud)

这将布尔值转换为数字;

style={ opacity: +!isFirstStep() }
Run Code Online (Sandbox Code Playgroud)


Teo*_*xim 8

TL;DR:避免Number构造函数,一元+;一直使用简单if的;求助于bool | 01 * bool如果您的项目中的基准以这种方式做得更好。

这是一个相当古老的问题,有很多有效的答案。我注意到的一点是,这里的所有基准都是无关紧要的——没有一个考虑分支 预测。此外,如今,JS 引擎不再简单地解释代码,而是将其JIT 编译为本地机器代码并在执行之前对其进行优化。这意味着,除了分支预测之外,编译器甚至可以用它们的最终值替换表达式。

现在,这两个因素如何影响布尔到整数转换的性能?让我们一探究竟吧!在我们进入基准测试之前,了解我们的基准测试很重要。对于转换,我们使用以下七种转换方法:

  • 数字构造函数: Number(bool)
  • If 语句(使用三元): bool ? 1 : 0
  • 一元运算符++bool
  • 按位或: bool | 0
  • 按位与: bool & 1
  • 按位加倍非: ~~bool
  • 数乘法: bool * 1

“转换”是指转换false0true11。每种转换方法运行 100000 次,测量操作数/毫秒。在下表中,转换方法将根据其结果进行分组。结果来自我的机器,它的 CPU 为 AMD Ryzen 7 4800HS。

第一个基准转换常数true

方法 边缘/铬 (V8) 火狐(蜘蛛猴)
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。我们的结果会改变吗?让我们运行这个基准测试看看。

方法 边缘/铬 (V8) 火狐(蜘蛛猴)
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 中,这些函数完成了所有工作。

我们还没有解决我们上面提到的一个因素:分支预测。在这个基准测试中,让我们将布尔变量更改为Math.random() < 0.01,这意味着 1% true、 99% false

方法 边缘/铬 (V8) 火狐(蜘蛛猴)
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 语句。不要变得聪明 - 浏览器通常会做得更好,并且通常意味着大多数情况。它们是这里所有方法中最易读和最清晰的。当我们处于可读性时,也许使用if (bool)而不是那个丑陋的三元!我希望 Javascript 拥有RustPython 所拥有的......
  • 真正需要时使用其余部分。也许您项目中的基准测试执行不合标准,并且您发现令人讨厌的if导致性能不佳 - 如果是这种情况,请随时进入无分支 编程!但是不要在那个兔子洞里钻得太深-1 * (a < b) + 1 * (a > b),相信我,没有人会从诸如此类的事情中受益。

我将永远感谢您阅读到最后——这是我第一个更长、更重要的 StackOverflow 答案,如果它对我有帮助和洞察力,它对我来说意味着整个世界。如果您发现任何错误,请随时纠正我!


  1. 定义了转换,因为它并不真正清楚布尔到整数的含义。例如,Go 根本不支持这种转换

  • 对这一努力表示支持,但我想不出当此类操作的性能很重要时的真实用例:) (3认同)

sil*_*ire 6

+!!允许您将其应用于变量,即使它是undefined

+!!undefined    // 0
+!!false        // 0
+!!true         // 1

+!!(<boolean expression>)  // 1 if it evaluates to true, 0 otherwise
Run Code Online (Sandbox Code Playgroud)


des*_*ise 6

JavaScript 中布尔到整数的转换可以通过以下方式完成:

  1. 使用Number()
  2. 使用三元
  3. 使用一元运算符
  4. 使用算术运算符
  5. 使用按位运算符
  6. 使用按位移位运算符

在之前的答案中已经涵盖了其中一些内容,但是,您可以找到一些缺失的内容,如下所示:

// using arithmetic operators

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

true - 0; // 1
false - 0; // 0

true * 1 // 1
false * 1 // 0

true / 1; // 1
false / 1; // 0
Run Code Online (Sandbox Code Playgroud)
// using bitwise operators

true & 1; // 1
false & 1; // 0

true | 0; // 1
false | 0; // 0

true ^ 0; // 1
false ^ 0; // 0
Run Code Online (Sandbox Code Playgroud)
// using bitwise shift operators

true >> 0; // 1
false >> 0; // 0

true >>> 0; // 1
false >>> 0; // 0

true << 0; // 1
false << 0; // 0
Run Code Online (Sandbox Code Playgroud)

这些之所以有效,是因为 JavaScript 在执行这些操作时会在内部将布尔值强制转换为其等效的整数。

NaN需要注意的重要一点是,当您不确定变量始终具有布尔值时,所有这些方法([使用三元运算符][2]除外)都可能返回。

为有兴趣了解更多信息的人写了一篇博客文章。