Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

197
Vistas
¿Cómo encontrar los nodejs hoja con recursividad en javascript?

Estoy tratando de entender la recursividad y me gusta resolver un problema similar como este: encontrar recursivamente a todos los niños del menú principal .

La diferencia entre mi problema y el del ejemplo anterior es que necesito que el resultado de la función sea una lista de nodejs hoja. Entonces, si toma los datos JSON a continuación y quería saber cuáles son los nodejs de hoja de menuId 1001, espero que el resultado sea ["1005", "1007", "1009"] . Si quisiera saber cuáles son los nodejs hoja a partir de 1004, espero que el resultado sea ["1007", "1009"]

 [
 {"menuId":"1001","depth":"1","parentId":"0"},
 {"menuId":"1002","depth":"1","parentId":"0"},
 {"menuId":"1003","depth":"2","parentId":"1001"},
 {"menuId":"1004","depth":"2","parentId":"1001"},
 {"menuId":"1005","depth":"3","parentId":"1003"}, 
 {"menuId":"1006","depth":"3","parentId":"1004"}, 
 {"menuId":"1007","depth":"4","parentId":"1006"}, 
 {"menuId":"1008","depth":"4","parentId":"1006"}, 
 {"menuId":"1009","depth":"5","parentId":"1008"},
]

Intenté alterar el código del enlace para resolver mi problema, pero parece que no puedo resolverlo:

 function getChildren(array, id) {
 return array.netuce((r, { menuId }) => {
 if (array.filter(x => x.parentId === id).length === 0) {
 r.push(menuId);
 } else {
 getChildren(array, menuId)
 }
 return r;
 }, []);

Cualquier consejo o ayuda será apreciada.

almost 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

EDITAR: Reelaborado porque no puedo leer.

La recursión no es un enfoque muy eficiente, dado que la estructura de datos que tiene está linealizada. Por lo tanto, primero convierto los datos en una estructura de árbol real, donde la recursividad puede brillar.

Un problema es que no tiene un árbol adecuado, ya que falta el node raíz. También asumí que no desea que se cambien sus datos de entrada, así que cloné sus datos para un enfoque no destructivo. Permitir que se cambien los datos de los items (agregar la propiedad de los children ) en lugar de copiarlos e insertar un node raíz ficticio habría simplificado considerablemente el código.

 const items = [
 {"menuId":"1001","depth":"1","parentId":"0"},
 {"menuId":"1002","depth":"1","parentId":"0"},
 {"menuId":"1003","depth":"2","parentId":"1001"},
 {"menuId":"1004","depth":"2","parentId":"1001"},
 {"menuId":"1005","depth":"3","parentId":"1003"}, 
 {"menuId":"1006","depth":"3","parentId":"1004"}, 
 {"menuId":"1007","depth":"4","parentId":"1006"}, 
 {"menuId":"1008","depth":"4","parentId":"1006"}, 
 {"menuId":"1009","depth":"5","parentId":"1008"},
];

const tree = {};
function treeify(items) {
 const roots = [];
 const lookup = {};
 for (const item of items) {
 lookup[item.menuId] = { ...item, children: [] };
 }
 for (const item of Object.values(lookup)) {
 if (item.parentId in lookup) {
 lookup[item.parentId].children.push(item);
 } else {
 roots.push(item);
 }
 }
 return roots;
}

function leafNodes(root) {
 if (root.children.length) {
 return root.children.flatMap(leafNodes);
 } else {
 return [root];
 }
}

const roots = treeify(items);
const node1001 = roots.find(item => item.menuId == "1001");
const leafNodesOf1001 = leafNodes(node1001);
console.log(leafNodesOf1001);
console.log(leafNodesOf1001.map(item => item.menuId));
// ["1005", "1007", "1009"]

almost 4 years ago · Santiago Trujillo Denunciar

0

Un enfoque que no es particularmente eficiente, pero es muy simple, es escanear recursivamente los datos para los hijos de una id dada. Si no hay ninguno, estamos en una hoja (suponiendo que la identificación realmente esté en la entrada). Si hay niños, simplemente flatMap nuestra función sobre sus id s. Se parece a esto:

 const leafDescendents = (items) => (id) => {
 const children = items .filter (({parentId}) => id == parentId) 
 return children .length == 0 
 ? items .find (({menuId}) => menuId == id) ? [id] : [] 
 : children .map (child => child.menuId) .flatMap (leafDescendents (items))
}

const items = [{menuId: "1001", depth: "1", parentId: "0"}, {menuId: "1002", depth: "1", parentId: "0"}, {menuId: "1003", depth: "2", parentId: "1001"}, {menuId: "1004", depth: "2", parentId: "1001"}, {menuId: "1005", depth: "3", parentId: "1003"}, {menuId: "1006", depth: "3", parentId: "1004"}, {menuId: "1007", depth: "4", parentId: "1006"}, {menuId: "1008", depth: "4", parentId: "1006"}, {menuId: "1009", depth: "5", parentId: "1008"}];


['1001', '1008', '1009', '0', '999'] .forEach (
 (id) => console .log (`"${id}":\t${JSON .stringify (leafDescendents (items) (id))}`)
)

Lo único un poco extraño es que esto:

 ? items .find (({menuId}) => menuId == id) ? [id] : [] 

parece que debería ser solo esto:

 ? [id]

Y podría ser, si cualquiera

  • (a) sabe que las entradas siempre serán el menuId de menú de uno de sus elementos

  • (b) no le importa que las entradas desconocidas devuelvan su propio valor, por ejemplo

     leafDescendents (items) ("999") //=> ["999"]
    

Si no te gusta esa rareza y sospechas que podrías estar alimentándola con id faltantes, entonces mantén la línea intacta. De lo contrario, puede usar la línea más simple.

almost 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda