Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/427.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在嵌套对象中查找任何假值的更好方法?_Javascript - Fatal编程技术网

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!==对象和对象值(…)