Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/442.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_Algorithm_Recursion - Fatal编程技术网

Javascript 检查一个对象是否是另一个对象';后代

Javascript 检查一个对象是否是另一个对象';后代,javascript,algorithm,recursion,Javascript,Algorithm,Recursion,我试图检查一个物体是否是另一个物体的后代。例如,obj2是obj1的后代: const obj1 = { a: 100, b: { c:{ d:100, e:200, f:3, g:50, h:10, i:{ j:{ x:50, y:100 } } } } } const obj2 = { i:{ j:

我试图检查一个物体是否是另一个物体的后代。例如,obj2是obj1的后代:

const obj1 = {
  a: 100,
  b: {
    c:{
      d:100,
      e:200,
      f:3,
      g:50,
      h:10,
      i:{
        j:{
          x:50,
          y:100
        }
      }
    }
  }
}
const obj2 = {
  i:{
    j:{
      x:50,
      y:100
    }
    
  }
}
我尝试使用递归来检查这一点,但它不正确。请问错在哪里?非常感谢你

function isDescendent(obj1,obj2) {
  //if both not object, compare their value
  if (typeof obj1 !== 'object' && typeof obj2 !== 'object') {
    return obj1 === obj2;
  }
  //if both object, compare their length first 
  if(Object.keys(obj1).length !== Object.keys(obj2).length) {
    return false;
  }
   
  //if both object with the same length, loop and compare each key 
  for (let key in obj1) {
    if(isDescendent(obj1[key],obj2)) {
      return true;
    }
  }
  return false;
}
我已经使用了deep object equality,但是您可以使用中的任何其他函数

就你的情况而言,这样的事情应该行得通

constobj1={a:100,b:{c:{d:100,e:200,f:3,g:50,h:10,i:{j:{x:50,y:100}
常量obj2={i:{j:{x:50,y:100}}
常量isNestedObject=(对象,NestedObject)=>
Object.entries(obj).some([k,v])=>{switch(true){
case Object.keys(nestedObj).includes(k)
&&_u.isEqual(nestedObj,{[k]:v}):
返回真值
案例v!==null&&typeof v==='object':
返回isNestedObject(v,nestedObject)
违约:
返回错误
}})
常数res=isNestedObject(对象J1、对象J2)
console.log(res)

您可以对父输入
T
和子输入
T
进行简单的类型分析-

函数isSubset(T,T)
{if(T?.constructor!==T?.constructor)
返回错误
else开关(t?构造函数)
{案例对象:
返回Object.keys(t).every(k=>isSubset(t[k],t[k]))
||key(T).some(k=>isSubset(T[k],T))
违约:
返回T==T
}
}
常数a={a:100,b:{c:{d:100,e:200,f:3,g:50,h:10,i:{j:{x:50,y:100}
常数b={i:{j:{x:50,y:100}}
console.log(isSubset(a,b))//true
log(isSubset(a,{y:100}))//true
log(isSubset(a,{y:100,x:50}))//true
log(isSubset(a,{y:'100}))//false
log(isSubset(a,{y:99}))//false

log(isSubset(a,{z:100}))//false
我的解决方案假定具有基本值字段的非循环对象。请注意,obj2不是obj1的完整子对象。它只有i键,而obj1中的c键有许多其他键

constobj1={a:100,b:{c:{d:100,e:200,f:3,g:50,h:10,i:{j:{x:50,y:100};
常量obj2={i:{j:{x:50,y:100}};
常量obj3={j:{x:50,y:100};
常量枚举子对象=o=>{
常数头=[o];
常量子对象=[];
while(heads.length){
const current=heads.shift();
子对象推送(当前);
如果(当前的类型=='object'){
heads.push(…Object.values(当前));
}
}
返回子对象;
}
常数等于=(a,b)=>a的类型!='对象“| |类型b!==”对象的
? 类型a==类型b&&a==类型b
:Object.keys(a).length==Object.keys(b).length
&&key(a).every(key=>等于(a[key],b[key]);
常量isNested=(a,b)=>
枚举子对象(a)。一些(子对象=>等于(子对象,b));
log(isNested(obj1,obj2));

log(isNested(obj1,obj3))在递归函数中,可以首先检查子代的所有键是否出现在
obj1
中。如果这样做,则递归可能发生在子代中每个键的
obj1
值上。如果不是,则递归可应用于
obj1
的所有值:

功能isDescendent(obj1、obj2){
if(!Object.keys(obj2).every(x=>obj1中的x)){
返回Object.key(obj1).some(x=>(obj1[x]==obj2的类型)和&isDescendent(obj1[x],obj2))
}
返回Object.keys(obj2).every(函数x){
if(obj1[x]==='object'类型和obj2[x]=='object'类型){
返回isDescendent(obj1[x],obj2[x])
}
返回obj1[x]==obj2[x]
});
}
常数a={a:100,b:{c:{d:100,e:200,f:3,g:50,h:10,i:{j:{x:50,y:100}
常数b={i:{j:{x:50,y:100}}
控制台日志(isDescendent(a,b))
log(isDescendent(a,{y:100}))
log(isDescendent(a,{y:100,x:50}))
log(isDescendent(a,{y:'100}))
log(isDescendent(a,{y:99}))

log(isdescedent(a,{z:100}))
据我所知,您想知道obj1是否从obj2继承,如果我错了,很抱歉,但如果我错了,那么您可以做的是检查它们的proto属性,因此您可以做的是

function isDescendent(obj1, obj2){
if(obj1.__proto==obj2.__proto__)
     {
            //Do something
     }
}
这段代码实际做的是检查我上面提到的proto属性,因此如果它们相等,这意味着object1从object2继承,或者在您的例子中是object2的后代。。。。
我不知道如何用递归来解决这个问题,但是如果你愿意用一个更简单的方法,这就是你应该用的方法。

这能回答你的问题吗@你好!谢谢你的回复!这似乎不一样。你可能想检查v===“object”
类型是否为null,但我认为这是可行的。哦,我明白了,给我30秒。使用
JSON.stringify
来比较对象是不可预测的。对象属性没有保证的顺序,因此
JSON.stringify({a:1,b:2})
不等于
JSON.stringify({b:2,a:1})
如果两个构造函数都不是
Object
呢。或者如果它们是用
对象创建的。创建(null)
?如果您有自定义类或对象,它们可以(应该)定义自己的比较逻辑。或者,他们可以将其内部状态切换到此通用
isSubset
功能。即,
myObj.isSubset(myObj2)
包括内部状态并将其传递给
isSubset
。为了提高最高程度的可重用性,类应该是围绕在普通数据上操作的普通函数的精简(哑)包装。否则,您将在每个需要它的类中复制相同的特性。对于具体的例子,请看我不认为用户非常关心具有相同构造函数的对象之间的特定比较规则,但他必须澄清这一点。我仍然认为最好检查它是否是类型为
的对象。然后你可以切换到对象构造函数,你可以向后切换。诸如
+
concat
之类的泛型函数无法识别任何自定义对象或c