Well, this is kind of hacky:
function b2n(boo) {
return boo ? 1 : 0;
}
if(b2n(opt1) + b2n(opt2) + b2n(opt3) !== 1) {
throw new Error(\"Exactly one o
You mentioned in your comment that this is coming from a commander options object.
You can do this more elegantly using Lodash:
if (_(options).values().compact().size() === 1)
If you only want to count a subset of the options, you can insert
.pick('a', 'b', 'c')
if ([opt1, opt2, opt3].reduce(function(x, y) { return x + !!y }, 0) == 1) {
// exactly one
};
ECMAScript 5 reduce function.
Assuming you had an array of options, you could do:
if(opts.filter(Boolean).length !== 1) {}
It seems to me though that you ought to have one variable with three possible states instead...
var opt = 'a'; // (or 'b', or 'c')
I think you are being too clever, what's wrong with:
var optionsSelected = 0;
if( opt1 ) optionsSelected++;
if( opt2 ) optionsSelected++;
if( opt3 ) optionsSelected++;
if( optionsSelected !== 1 ) {
throw new Error("Exactly one option must be set");
}
Of course I can play the clever game too:
if( opts.filter(Boolean).length !== 1 ) {
throw new Error("Exactly one option must be set");
}
You can do this :
if ( !!opt1 + !!opt2 + !!opt3 !== 1 ) {
It works because
!!
makes a boolean from any value (true
if the objects evaluates as true
in if(value)
) 1
for true
and 0
for false
.@spudly is on the right track, but it could be a little more compact:
if( [opt1,opt2,opt3].filter(function(x){return x}).length!==1 ) {
throw new Error("Exactly one option must be set");
}
See ES5's filter method for more information.