Я пишу функцию для расчета глубины объекта.
Вот моя рекурсивная версия, которая, кажется, работает должным образом:
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]]
, но вместо этого он принимает только последнее свойство.На самом деле проблема в том, как перебрать все ключи на всех уровнях глубины, как в рекурсивной версии.
Есть предложения о том, как реализовать этот алгоритм итеративным способом?
Даже любые предложения о том, как улучшить рекурсивный вариант (или, если я что-то упустил), более чем приветствуются.
ps НЕТ ЗАГРУЗКИ, ПОДДЕРЖКИ, РАМДА или чего-либо еще.Просто Ваниль JS