10

好吧,这有点骇人听闻:

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 和 Node 解决方案。

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

4

6 回答 6

11

假设您有一系列选项,您可以执行以下操作:

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

但在我看来,你应该有一个具有三种可能状态的变量......

var opt = 'a'; // (or 'b', or 'c')
于 2013-06-25T17:57:56.920 回答
6

你可以这样做 :

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

它有效,因为

  • !!从任何值生成一个布尔值(true如果对象评估为truein if(value)
  • 添加布尔值时,您会得到1fortrue0for false
于 2013-06-25T17:53:32.057 回答
1

我认为你太聪明了,有什么问题:

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");
 }
于 2013-06-25T17:58:03.933 回答
1

您在评论中提到这来自指挥官选项对象。

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

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

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

.pick('a', 'b', 'c')
于 2013-06-25T18:00:58.410 回答
1
if ([opt1, opt2, opt3].reduce(function(x, y) { return x + !!y }, 0) == 1) {
    // exactly one
};

ECMAScript 5减少函数。

于 2013-06-25T18:03:49.313 回答
0

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

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

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

于 2013-06-25T18:16:30.457 回答