Javascript 在嵌套对象中查找任何假值的更好方法?
如果我有一个对象,例如:Javascript 在嵌套对象中查找任何假值的更好方法?,javascript,Javascript,如果我有一个对象,例如: const obj = { field1: { subfield1: true, subfield2: true, }, field2: { subfield3: true, }, field3: { subfield4: false, subfield5: true, } } const isObj = obj => obj && obj.constructor === Objec
const obj = {
field1: {
subfield1: true,
subfield2: true,
},
field2: {
subfield3: true,
},
field3: {
subfield4: false,
subfield5: true,
}
}
const isObj = obj => obj && obj.constructor === Object;
const findFalseRecursively = obj => {
for (const field in obj) {
if (isObj(obj[field]))
return findFalseRecursively(obj[field])
if (obj[field] === false)
return true
}
}
然后,如果值是false
,我可以执行嵌套for循环以返回true
const findFalse = obj => {
for (const field in obj) {
for (const subfield in obj[field]) {
if (!obj[field][subfield]) return true
}
}
}
如果这个对象不是嵌套的,它会更容易一些,我可以这样做
const findFalse = obj => Object.keys(obj).some(prop => !obj[prop]);
这两种方法都不能满足我的需要,因为对象可以有2个、3个或更多嵌套属性。我想出了一个递归的方法来解决这个问题,比如:
const obj = {
field1: {
subfield1: true,
subfield2: true,
},
field2: {
subfield3: true,
},
field3: {
subfield4: false,
subfield5: true,
}
}
const isObj = obj => obj && obj.constructor === Object;
const findFalseRecursively = obj => {
for (const field in obj) {
if (isObj(obj[field]))
return findFalseRecursively(obj[field])
if (obj[field] === false)
return true
}
}
但我想知道是否有更干净或更有效的方法来实现这一点
我希望函数返回它看到的第一个
false
值,并立即跳出函数/for循环。您可以通过在对象的字符串表示形式中搜索来实现,如下所示:
const o={
字段1:{
子域1:对,
子域2:对,
},
字段2:{
子域3:对,
},
字段3:{
子域4:假,
子域5:对,
}
};
const containsFalse=(obj)=>/\“+\”\:false[^\”]/.test(JSON.stringify(obj));
控制台日志(containsFalse(o));
log(containsFalse({a::false“}));
您可以从对象中获取值,并通过短路进行迭代
const
hasTrue=object=>object
.值(对象)
.some(v=>v==false | | v&&typeof v==='object'&&hasTrue(v)),
object={field1:{subfield1:true,subfield2:true},field2:{subfield3:true},field3:{subfield4:false,subfield5:true};
console.log(hasTrue(object));
这里是一个简单的递归解决方案,它使用对象.value
、平面
和部分
函数值(obj){
if(typeof obj==='object')返回object.values(obj.map)(toValues);
返回obj;
}
const findFalse=obj=>toValues(obj).flat().some(v=>v==false)
const res=findFalse(obj);
console.log(res);
常量对象={
字段1:{
子域1:对,
子域2:对,
},
字段2:{
子域3:对,
},
字段3:{
子域4:假,
子域5:对,
}
}
如果存在任意嵌套,则无法避免递归。不过,您可以使其更干净:
const isObj = obj => obj && typeof obj == "object";
const findFalseRecursively = val => {
if (val === false)
return true;
if (isObj(val))
for (const field in val) {
if (findFalseRecursively(val[field]))
return true;
return false;
}
你想要一个
true
/false
?还是所有的false
?请添加想要的结果。@NinaScholz他从来没有提到他想要所有的对象都false
,只是想检测一个对象是否包含false
的值。所以我的猜测是:在第一个false
,re把true
。我已经澄清了这个问题。这里有一个问题。你的递归正确吗?它会在你的第一个例子中失败吗?它是否需要在某个时候返回false
?@Ben你绝对正确,但这不是问题。是的,只是指出它,以防有人需要将它与虚假的值一起使用:)@Ben ah好的,我明白了y fail:)对于containsFalse({a:::false“})
失败。很酷的解决方案,但为了清楚起见,我不会在同一语句中声明函数和变量。但这可能是“我的事情”“我建议将类型防护装置从部分
中拉出,并将其放置在初始对象的前面。值
。这不会改变结果,但可以防止最初传递的坏值。例如:未定义!==对象&&null!==对象和对象值(…)