Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/453.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 仅检查一个布尔选项集_Javascript_Node.js - Fatal编程技术网

Javascript 仅检查一个布尔选项集

Javascript 仅检查一个布尔选项集,javascript,node.js,Javascript,Node.js,嗯,这有点骇人: function b2n(boo) { return boo ? 1 : 0; } if(b2n(opt1) + b2n(opt2) + b2n(opt3) !== 1) { throw new Error("Exactly one option must be set"); } 有没有更好的方法在Javascript中实现这一点?使用任何 更智能的布尔/数字处理 秘密阵列或功能操作 等等。欢迎使用Javascript和节点解决方案 在我的实际问题中,选

嗯,这有点骇人:

function b2n(boo) {
    return boo ? 1 : 0;
}

if(b2n(opt1) + b2n(opt2) + b2n(opt3) !== 1) {
    throw new Error("Exactly one option must be set");
}
有没有更好的方法在Javascript中实现这一点?使用任何

  • 更智能的布尔/数字处理
  • 秘密阵列或功能操作
等等。欢迎使用Javascript和节点解决方案

在我的实际问题中,选项来自节点模块commander,所以我不是在处理真正的布尔值,而是真实和虚假的东西。也可能有指挥官解决方案。

您可以执行以下操作:

if ( !!opt1 + !!opt2 + !!opt3 !== 1 ) {
它之所以有效是因为

  • 根据任何值生成布尔值(
    true
    如果对象在
    if(value)
    中的计算结果为
    true
  • 当添加布尔值时,对于
    true
    您会得到
    1
    ,对于
    false
    您会得到
    0

假设您有一系列选项,您可以:

if(opts.filter(Boolean).length !== 1) {}
在我看来,你应该有一个变量,有三种可能的状态

var opt = 'a'; // (or 'b', or 'c')

我觉得你太聪明了,怎么了

var optionsSelected = 0;
if( opt1 ) optionsSelected++;
if( opt2 ) optionsSelected++;
if( opt3 ) optionsSelected++;

if( optionsSelected !== 1 ) {
    throw new Error("Exactly one option must be set");
}
当然,我也可以玩这个聪明的游戏:

 if( opts.filter(Boolean).length !== 1 ) {
     throw new Error("Exactly one option must be set");
 }

您在评论中提到这是来自commander options对象

您可以通过以下方式更优雅地执行此操作:

如果只想计算选项的子集,可以插入

.pick('a', 'b', 'c')

ECMAScript 5函数。

@spudy的思路是正确的,但它可以更紧凑一些:

if( [opt1,opt2,opt3].filter(function(x){return x}).length!==1 ) {
    throw new Error("Exactly one option must be set");
}

有关更多信息,请参阅。

您解决的用例是什么?您正在验证用户输入吗?如果是这样,您可以使用单选按钮吗?@ChadCook这是服务器端。它是从
node.js
commander命令的。在我的实际问题中,它默认为
opt3
,因此我实际上检查了
>1
。您如何运行Javascript服务器端?(true+false==1)。布尔值自动转换为int@DmitryTeplyakov是的,需要使用
确保值也是布尔值。如果他知道它们是布尔值,那么!!是不必要的,因此您可以将其更改为if(opt1+opt2+opt3!=1){}@spudy我不知道这些值是否为布尔值。这在问题中并不清楚。事实上,它们不是,无论如何,这是最安全的方法。可读性较差,但可以将表达式简化为:
!opt1+!opt2+!opt3==2
(2是选项数,3减去一个真实选项)。@Paulpro是的,这是真的,但我认为不值得。在我看来,与目标的语义差距太大了。Javascript有很多广为接受的模式,可以让你在一行可读的代码中完成需要8个字符的工作。我更喜欢“聪明”的模式,因为它们被很好地理解(因此并不聪明)。我对Javascript相当熟悉,因此还不知道这些。有关“聪明”解决方案的示例,请参阅其他所有答案。以前应该给出聪明的答案,因为人是易变的。啊,这就是你如何流畅地使用lodash的。为什么还要费心传递匿名函数呢?只要使用
if(opts.filter(Boolean).length!==1){}
。或者,即使使用匿名函数,只返回
v
也更有意义。感谢您建议只使用布尔函数。没有想到这一点,这是一个很大的进步。至于仅仅返回v,我最初是这样编码的,但由于询问者一开始不确定值是否是布尔值,所以对其进行了更改。没问题!是的,如果是这样简单的话,我试着想一种方法来传递一个内置函数而不是自定义函数。对于返回
v
,它是有效的-从传递给
过滤器的回调返回的值被评估为truthy,而不是
true
,因此内容是否为布尔值无关紧要。例如,如果你只是
返回v
将不会通过,而
“a”
将通过。使用
Boolean
在技术上也可以做同样的事情,只是很快就会变得聪明,@spudy!我真希望我想到了那一点。
if ([opt1, opt2, opt3].reduce(function(x, y) { return x + !!y }, 0) == 1) {
    // exactly one
};
if( [opt1,opt2,opt3].filter(function(x){return x}).length!==1 ) {
    throw new Error("Exactly one option must be set");
}