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中实现这一点?使用任何
- 更智能的布尔/数字处理
- 秘密阵列或功能操作
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");
}