Javascript 检查一个对象是否是另一个对象';后代
我试图检查一个物体是否是另一个物体的后代。例如,obj2是obj1的后代: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:
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