gpt4 book ai didi

javascript - 以迭代方式查找对象的深度

转载 作者:搜寻专家 更新时间:2023-11-01 05:03:15 27 4
gpt4 key购买 nike

我正在编写一个用于计算对象深度的函数。

这是我的递归版本,它似乎按预期工作:

function findDepth(obj, firstCall = true) {
if (firstCall && typeof obj !== "object") {
return -1;
}
return Object.keys(obj).reduce((max, k) => {
if (typeof obj[k] === "object" && obj[k] !== null) {
const val = findDepth(obj[k], false) + 1;
if (val > max) {
max = val;
}
}
return max;
}, 1);
}

const input1 = {
a: {
b: "test",
c: {
d: {
e: {
f: [1, 2, 3],
g: {
a: null,
z: {
d: "casdsadasdsa",
q: {
z: {
i: undefined
}
}
}
}
}
},
c: {
a: "sad"
}
},
d: {
e: 5
}
},
b: {
c: {
d: "dsada"
}
}
};

const input2 = {
w: {
d: "hello",
f: {
g: "dsadas",
z: {
b: "dsajkdasjldk",
q: {
w: {
z: "dsajkdasjdla"
}
}
},
h: "dsiaodsiad"
}
},
a: "test",
b: "test2",
c: {
d: "hello",
f: {
g: "dsadas",
z: {
b: "dsajkdasjldk"
},
h: "dsiaodsiad"
}
},
e: "bye"
};

console.log(findDepth(input1));
console.log(findDepth(input2));

现在我正在尝试编写一个迭代版本,但我找不到使循环工作的最佳方法。

function findDepthIterative(obj) {
if (typeof obj !== "object") {
return -1;
}
let max = 1;
let copy = Object.assign({}, obj);
let keys = Object.keys(copy);
while (keys.length) {
if (typeof copy[keys[0]] !== "object" && copy[keys[0]] !== null) {
delete copy[keys[0]];
keys = Object.keys(copy);
} else {
max++;
copy = Object.assign({}, copy[keys[0]]);
keys = Object.keys(copy);
}
}
return max;
}

const input1 = {
a: {
b: "test",
c: {
d: {
e: {
f: [1, 2, 3],
g: {
a: null,
z: {
d: "casdsadasdsa",
q: {
z: {
i: undefined
}
}
}
}
}
},
c: {
a: "sad"
}
},
d: {
e: 5
}
},
b: {
c: {
d: "dsada"
}
}
};

const input2 = {
w: {
d: "hello",
f: {
g: "dsadas",
z: {
b: "dsajkdasjldk",
q: {
w: {
z: "dsajkdasjdla"
}
}
},
h: "dsiaodsiad"
}
},
a: "test",
b: "test2",
c: {
d: "hello",
f: {
g: "dsadas",
z: {
b: "dsajkdasjldk"
},
h: "dsiaodsiad"
}
},
e: "bye"
};

console.log(findDepthIterative(input1));
console.log(findDepthIterative(input2));

正如您从输出和代码中看到的,它只采用循环内的第一个属性:

while (keys.length) {
if (typeof copy[keys[0]] !== "object" && copy[keys[0]] !== null) {
delete copy[keys[0]];
keys = Object.keys(copy);
} else {
max++;
copy = Object.assign({}, copy[keys[0]]);
keys = Object.keys(copy);
}
}

我的想法是每次迭代都删除该属性,但我的方法不对。我试图用 copy[keys[keys.length - 1]] 来改变它,但这样它只需要最后一个属性。实际上,问题是如何在所有深度级别上循环遍历所有键,就像在递归版本中一样。

关于如何以迭代方式实现此算法的任何建议?

甚至任何关于如何改进递归的建议(或者如果我遗漏了什么)都非常受欢迎。

附注没有 LOADASH、UNDERSCORE、RAMDA 或其他任何东西。只是 Vanilla JS

最佳答案

您只需要保留一个堆栈并将 child 插入其中,同时跟踪当前深度。您可以通过将 [depth, obj] 数组压入堆栈,然后在 pop() 向深度添加一个,然后再压入子级来跟踪这一点。

const input1  = {w: {d: "hello",f: {g: "dsadas",z: {b: "dsajkdasjldk",q: {w: {z: "dsajkdasjdla"}}},h: "dsiaodsiad"}},a: "test",b: "test2",c: {d: "hello",f: {g: "dsadas",z: {b: "dsajkdasjldk"},h: "dsiaodsiad"}},e: "bye"};


function findDepthIterative(obj) {
if (typeof obj !== "object") {
return -1;
}
let max = 0;
// current depth, children
let stack = [[0, Object.values(obj)]];

while(stack.length){
let [depth, cur] = stack.pop()
if (depth > max) max = depth

if (typeof cur === "object" && cur !== null){
Object.values(cur).forEach(c => stack.push([depth+1, c]))
}
}
return max
}


console.log(findDepthIterative(input1))

// sanity check:
const depth0 = {}
const depth1 = {a:1}
const depth2 = {a:{b:2}}

console.log(findDepthIterative(depth0))
console.log(findDepthIterative(depth1))
console.log(findDepthIterative(depth2))

关于javascript - 以迭代方式查找对象的深度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54032094/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com