Sé cómo convertir funciones recursivas simples con una pila (como la que se describe aquí ), sin embargo, algunas funciones recursivas tienen una parte complicada que no sé cómo implementar. Las funciones recursivas más simples no cambian las variables locales de la persona que llama (por persona que llama me refiero a la función que se llama a sí misma) o, en otras palabras, las funciones recursivas más simples no cambian sus variables locales en función del valor devuelto por la llamada, pero se vuelve complicado cuando necesita cambiar eso y no sé cómo hacer lo mismo con la implementación de la pila. Aquí hay un ejemplo simplificado:
const obj = { src: { size: 0, children: { api: { size: 0, children: { api_2: { size: 0, children: { 'file1.js': { size: 2, }, 'file2.js': { size: 2, }, }, }, api_1: { size: 0, children: { 'test1.js': { size: 1, }, 'test2.js': { size: 1, }, }, }, }, }, }, }, }; const recursive = (object) => { if (object.children) { const currentChildren = object.children; Object.entries(currentChildren).forEach(([, child]) => { object.size += recursive(child); }); return object.size; } else { return object.size; } }; recursive(obj.src); console.log(obj.src.size); console.log(obj.src.children.api.size); console.log(obj.src.children.api.children.api_1.size); console.log(obj.src.children.api.children.api_2.size); // Output: 6 6 2 4Si mi pregunta es confusa, simplemente implementar esta función recursiva con una pila puede ayudarme a entender mucho mi problema.
Puede usar una búsqueda en profundidad primero con una pila haciendo estallar el último elemento con su padre y agregar los nodos visitados nuevamente si tiene hijos. La flag impide agregarlo de nuevo. Este enfoque visita los nodos dos veces, uno para buscar el nodo de mayor profundidad y otro para actualizar la propiedad de size .
const update = object => { const stack = [[object]]; while (stack.length) { const [o, p, flag] = stack.pop(); if (!flag && o.children) { stack.push([o, p, true]); Object.values(o.children).forEach(q => stack.push([q, o])); } else if (p) p.size += o.size; } }, obj = { src: { size: 0, children: { api: { size: 0, children: { api_2: { size: 0, children: { 'file1.js': { size: 2 }, 'file2.js': { size: 2 } } }, api_1: { size: 0, children: { 'test1.js': { size: 1 }, 'test2.js': { size: 1 } } } } } } } }; update(obj.src); console.log(obj.src.size); // 6 console.log(obj.src.children.api.size); // 6 console.log(obj.src.children.api.children.api_1.size); // 4 console.log(obj.src.children.api.children.api_2.size); // 2 console.log(obj.src); .as-console-wrapper { max-height: 100% !important; top: 0; }