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

125
Vistas
JavaScript: Agregar resultado de recursión a la matriz y devolverlo

Tengo un objeto anidado y mi objetivo es obtener la ruta hasta que un par clave-valor coincida en una matriz.

Mi implementación actual implementa esto mediante cadenas y concatenando las cadenas con el punto (".").

Sin embargo, en lugar de eso, me gustaría agregar todos los resultados intermedios a la matriz y presionarlos. Pero de alguna manera esto no funciona.

Código con datos de ejemplo


 const data = [ { parentId: "1111", name: "Audi", children : [ { parentId: "2222", name: "Benz", children : [ { parentId: "3333", name: "VW", children : [ ] } ] } ] } ] const pathTo = (array, target) => { var result; array.some(({ parentId, name, children = [] }) => { if (parentId === target) { return result = JSON.stringify({"parentId" : parentId, "name" : name}); } var temp = pathTo(children, target) if (temp) { return result = JSON.stringify({"parentId" : parentId, "name" : name}) + "." + temp; } }); return result; }; console.log(pathTo(data, "3333"))

Resultado actual


 {"parentId":"1111","name":"Audi"}.{"parentId":"2222","name":"Benz"}.{"parentId":"3333","name":"VW"}

=> El Camino concatenado con una cadena. Pero me gustaría :

Resultado Esperado


 [ "{"parentId":"1111","name":"Audi"}", "{"parentId":"2222","name":"Benz"}"{"parentId":"3333","name":"VW"}"]

=> una matriz con todos los elementos en orden posterior.

about 4 years ago · Juan Pablo Isaza
3 Respuestas
Responde la pregunta

0

Podría devolver una matriz o undefined .

 const data = [{ parentId: "1111", name: "Audi", children : [{ parentId: "2222", name: "Benz", children : [{ parentId: "3333", name: "VW", children : [] }] }] }], pathTo = (array, target) => { let result; array.some(({ parentId, name, children = [] }) => { if (parentId === target) { result = [{ parentId: parentId, name: name }]; return true; } const temp = pathTo(children, target) if (temp) { result = [{ parentId: parentId, name: name }, ...temp]; return true; } }); return result; }; console.log(pathTo(data, "3333"))
 .as-console-wrapper { max-height: 100% !important; top: 0; }

about 4 years ago · Juan Pablo Isaza Denunciar

0

Prefiero dividir problemas como este en pedazos y hacer que al menos algunos sean más genéricos en el proceso.

 function * traversePaths (xs, path = []) { for (let x of xs) { const newPath = [...path, x] yield newPath yield * traversePaths (x .children || [], newPath) } } const deepFindPath = (pred) => (xs) => { for (let path of traversePaths (xs)) { if (pred (path [path.length - 1])) {return path} } } const pathByParentId = (target) => deepFindPath (({parentId}) => parentId == target) const data = [{parentId: "1111", name: "Audi", children : [{parentId: "2222", name: "Benz", children : [{parentId: "3333", name: "VW", children : []}]}]}] // stringified to avoid SO's `/**id:4**/` - `/**ref:4**/,` notation console .log (JSON .stringify ( pathByParentId ('3333') (data) , null, 4))
 .as-console-wrapper {max-height: 100% !important; top: 0}

Aquí, traversePaths es una función generadora que toma cualquier matriz cuyos elementos tengan propiedades children (opcionales y recursivas) y la atraviesa (preordenar) produciendo una matriz de nodos de objetos/subobjetos para cada ruta en la matriz.

deepFindPath devuelve la ruta al primer nodo que coincide con el predicado proporcionado.

Estas dos funciones son genéricas. Luego, para resolver su problema, escribimos el pathByParentId simple, que simplemente acepta una identificación de destino y pasa a deepFindPath una función que prueba si la propiedad parentId del nodo coincide con esa identificación de destino. Devolverá la ruta al primer nodo coincidente, o undefined si nada coincide.

Su salida solicitada coincidió con la anterior, excepto que no mencionó children nodos secundarios. Prefiero este retorno, solo referencias simples a los nodos existentes. Pero si realmente no quieres a los niños, entonces puedes hacer:

 const pathByParentId = (target) => ( data, res = deepFindPath (({parentId}) => parentId == target) (data) ) => res && res .map (({children, ...rest}) => rest)

Si bien podríamos hacer esto en la función transversal, haría que la función fuera menos genérica y probablemente menos útil. Pero si quisiera hacerlo, podría mantener la versión original de pathByParentId y reemplazar traversePaths con esto:

 function * traversePaths (xs, path = []) { for (let {children, ...rest} of xs) { const newPath = [...path, rest] yield newPath yield * traversePaths (children || [], newPath) } }

Esto es menos flexible que la versión anterior, pero aún enumera genéricamente las rutas a cualquier matriz cuyos elementos tengan propiedades children (opcionales y recursivas). Los elementos de esas listas son objetos nuevos, similares al original pero sin las propiedades children .

about 4 years ago · Juan Pablo Isaza Denunciar

0

Si está de acuerdo con el uso de una dependencia, lo haría en su lugar. Aquí hay una solución usando object-scan .

 .as-console-wrapper {max-height: 100% !important; top: 0}
 <script type="module"> import objectScan from 'https://cdn.jsdelivr.net/npm/object-scan@18.1.2/lib/index.min.js'; const data = [{ parentId: '1111', name: 'Audi', children: [{ parentId: '2222', name: 'Benz', children: [{ parentId: '3333', name: 'VW', children: [] }] }] }]; const find = (obj, v) => objectScan(['**'], { abort: true, filterFn: ({ value }) => value === v, rtn: ({ parents }) => parents .filter((p) => !Array.isArray(p)) .reverse() .map(({ parentId, name }) => ({ parentId, name })) })(obj); console.log(find(data, '3333')); /* => [ { parentId: '1111', name: 'Audi' }, { parentId: '2222', name: 'Benz' }, { parentId: '3333', name: 'VW' } ] */ </script>

Descargo de responsabilidad: soy el autor de object-scan

about 4 years ago · Juan Pablo Isaza 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