我想验证一个具有三个布尔属性的对象,其中一个(只有一个)必须为true。最好的检查方法是什么?
我想到了这个
var t1 = obj.isFirst ? 1 : 0,
t2 = obj.isSecond ? 1 : 0,
t3 = obj.isThird ? 1 : 0;
var valid = (t1 + t2 + t3) === 1;
这很好,但感觉有点像业余爱好者的解决方案:-)
是否有更好的方法?例如使用异或(^)?
答案 0 :(得分:19)
您可以过滤Object.values并检查长度是否为1
let obj = {
a: true,
b: false,
c: false
};
let oneTrue = Object.values(obj).filter(e => e === true).length === 1;
console.log(oneTrue);
@deceze发表评论
对象中应该有更多属性:
[obj.a, obj.b, obj.c].filter(Boolean)...
请注意,在您的情况下,向您的对象添加为您进行检查的方法可能很有意义
let obj = {
a: false,
b: false,
c: false,
isValid() {
return this.a + this.b + this.c === 1;
}
};
console.log(obj.isValid());
答案 1 :(得分:9)
您可以使用array.reduce:
input
答案 2 :(得分:7)
使用:
obj.isFirst + obj.isSecond + obj.isThird === 1
假设可以确定这些值是布尔值,并且没有什么不同。您可以根据需要添加明确的转化,例如:
Number(obj.isFirst) + Number(obj.isSecond) + Number(obj.isThird) === 1
但是JavaScript也会隐式为您执行此转换。
答案 3 :(得分:4)
反之亦然,看来您正在尝试对可能具有3种可能状态的物体进行建模。不要将其表示为3个布尔值,而是将其表示为具有3个可能值的变量:
gem 'cocoapods'
如果要使用布尔值之一:
const STATES = ['STATE_A', 'STATE_B', 'STATE_C'];
let value = 'STATE_A';
如果您想验证doSomethingDependingOnBooleanC(value === `STATE_C`);
是否符合您的期望(三种可能的状态之一):
value
答案 4 :(得分:2)
您可以在一行中完成此操作,但不容易阅读。但是,如果混淆是您的目标,请继续阅读。
由于obj.isFirst
,obj.isSecond
和obj.isThird
均为0
或1
,因此您可以在两者之间使用按位XOR运算符^
他们:
(obj.isFirst ^ obj.isSecond ^ obj.isThird) ^ (obj.isFirst && obj.isSecond && obj.isThird)
我们需要对obj.isFirst && obj.isSecond && obj.isThird
进行XOR,因为obj.isFirst ^ obj.isSecond ^ obj.isThird
的值为true
。
答案 5 :(得分:2)
怎么样:
var valid = (obj.isFirst + obj.isSecond + obj.isThird) === 1;
注意:总和的返回值是一个整数,它将true转换为1,将false转换为0。因此,您实际上不需要boolValue ? 1 : 0
请参阅此结果集以供参考:
console.log(true + false + false) // 1
console.log(false + false + false) // 0
console.log(false + false + true) // 1
console.log(1 + false + 0) // 1
console.log(false + 1 + 1) // 2
还要让我指出,如果您想要显式转换并且您的数据是字符串,则可能会遇到此问题。因此,我宁愿使用Boolean
而不是Number
。
var a = "true",
b = false,
c = false;
var valid = Number(a) + Number(b) + Number(c);
console.log(valid); // NaN
var a = "true",
b = false,
c = false;
var valid = Boolean(a) + Boolean(b) + Boolean(c);
console.log(valid); // 1
答案 6 :(得分:1)
将其包装在名为“ ensureOnlyOnePropertyIsTruthy”的函数中。让它带有属性名称列表以及对象,然后填充您想要包含的所有丑陋,高性能的代码。没人需要阅读内部原理,因为您的函数为他们提供了唯一必要的上下文。
答案 7 :(得分:-2)
只需要一些奥术就可以了:
var valid = obj.isFirst ? !(obj.isSecond || obj.isThird) : (obj.isSecond ^ obj.isThird)