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

164
Vistas
Encuentre la ruta a TODOS los valores clave coincidentes en el objeto anidado

Tengo una función que me da la ruta al primer hallazgo de un objeto anidado donde la clave y el valor coinciden.

 function getPath(obj, givenKey, givenValue) { for(var key in obj) { if(obj[key] && typeof obj[key] === "object") { var result = getPath(obj[key], givenValue, givenKey); if(result) { result.unshift(key) return result; } } else if(obj[key] === givenValue && key === givenKey ) { return [key]; } } }

Data de muestra

 var myObj = [ { "name": "needle", "children": [ { "name": "group2", "children": [ { "name": "item0" }] }] }, { "name": "item1" }, { "name": "needleGroup", "children": [ { "name": "needleNestedGroup", "children": [ { "name": "item3" }, { "name": "needleNestedDeeperGroup", "children": [ { "name": "needle" }] }] }] }];

Rendimiento esperado

 getPath(myObj, "name", "needle"): [0, "name"] ["2","children","0","children","1","children","0","name"]

Sin embargo, ahora tengo un objeto que contiene estos valores-clave varias veces, por lo que tengo varias coincidencias.

¿Cómo puedo ponerlos todos en una matriz? Mi función actual simplemente se detiene después de encontrar la primera coincidencia. El hecho de que sea recursivo me complica mucho las cosas.

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

0

Escribiría esto encima de una función findAllPaths más genérica que acepta un predicado y encuentra las rutas de todos los nodos en el objeto que coinciden con ese predicado. Con eso, findPathsByName es tan simple como (target) => findAllPaths (({name}) => name == target) .

A su vez, construyo findAllPaths en pathEntries , variantes de las cuales uso todo el tiempo . Esta función convierte un objeto en una matriz de pares ruta/valor. Algunas versiones solo generan los nodos hoja. Este lo genera para todos los nodos, incluida la raíz (con una ruta vacía). La idea básica de esta función es convertir algo como:

 {a: 'foo', b: {c: ['bar', 'baz'], f: 'qux'}}

dentro de esto:

 [ [[], {a: 'foo', b: {c: ['bar', 'baz'], f: 'qux'}}], [['a'], 'foo'], [['b'], {c: ['bar', 'baz'], f: 'qux'}], [['b', 'c'], ['bar', 'baz']], [['b', 'c', 0], 'bar'], [['b', 'c', 1], 'baz'], [['b', 'f'], 'qux'] ]

donde el primer elemento de cada subarreglo es una ruta y el segundo una referencia al valor en esa ruta.

Esto es lo que podría parecer:

 const pathEntries = (obj) => [ [[], obj], ...Object (obj) === obj ? Object .entries (obj) .flatMap ( ([k, x]) => pathEntries (x) .map ( ([p, v]) => [[Array .isArray (obj) ? Number (k) : k, ... p], v] ) ) : [] ] const findAllPaths = (predicate) => (o) => [...pathEntries (o)] .filter (([p, v]) => predicate (v, p)) .map (([p]) => p) const findPathsByName = (target) => findAllPaths (({name}) => name == target) const myObj = [{name: "needle", children: [{name: "group2", children: [{name: "item0"}]}]}, {name: "item1"}, {name: "needleGroup", children: [{name: "needleNestedGroup", children: [{name: "item3"}, {name: "needleNestedDeeperGroup", children: [{name: "needle"}]}]}]}] console .log (findPathsByName ('needle') (myObj))
 .as-console-wrapper {max-height: 100% !important; top: 0}

La pregunta solicitaba valores de cadena para los índices de matriz. Prefiero los valores enteros como se hace aquí, pero simplificas un poco la función:

 - ([p, v]) => [[Array .isArray (obj) ? Number (k) : k, ... p], v] + ([p, v]) => [[k, ... p], v]
about 4 years ago · Juan Pablo Isaza Denunciar

0

En lugar de devolver el valor, puede enviarlo a una matriz y seguir iterando.

Al final de la función, return la matriz.

 function getPath(obj, givenKey, givenValue) { let matches = []; for (var key in obj) { if (obj[key] && typeof obj[key] === "object") { var result = getPath(obj[key], givenValue, givenKey); if (result) { result.unshift(key) matches.push(...result); } } else if (obj[key] === givenValue && key === givenKey) { matches.push(key); } } return matches; }

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