检查一个布尔选项集合

那么,这是一种哈克:

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中? 使用任何的

  • 更智能的布尔/数字处理
  • 偷偷摸摸的arrays或function操作

等等。 JavaScript和节点解决scheme的欢迎。

在我的实际问题中,选项来自Node模块的指挥官,所以我不处理真正的布尔值,只是真正的和虚假的东西。 也可能有一个指挥官的解决scheme。

假设你有一系列的select,你可以这样做:

 if(opts.filter(Boolean).length !== 1) {} 

在我看来,你应该有三个可能的状态,而不是一个variables…

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

你可以这样做 :

 if ( !!opt1 + !!opt2 + !!opt3 !== 1 ) { 

这是因为

  • !! 从任何值(如果对象在if(value)评估为trueif(value)一个布尔if(value)
  • 当添加布尔值时,你得到1true0false

你在你的评论中提到,这是来自指挥官选项对象。

您可以使用Lodash更优雅地做到这一点 :

 if (_(options).values().compact().size() === 1) 

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

 .pick('a', 'b', 'c') 
 if ([opt1, opt2, opt3].reduce(function(x, y) { return x + !!y }, 0) == 1) { // exactly one }; 

ECMAScript 5 减lessfunction。

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

 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"); } 

@spudly是在正确的轨道上,但它可以更紧凑一点:

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

有关更多信息,请参阅ES5的过滤方法 。