Estoy tratando de crear una función que debe hacer lo siguiente:
toma un objeto JavaScript como primer parámetro
el objeto puede tener cualquier estructura y profundidad
toma una cadena que contiene una clave como segundo parámetro
devuelve un mapa con todos los valores que se encuentran para esa clave dentro del objeto o la clave en el mapa resultante será la ruta a la clave dentro del objeto donde "/" se usa como separador o la clave raíz para el mapa es el nombre del objeto
el resultado tiene que ser algo como:
let obj = { id: 1, b: "value", c: 404, d: { id: "value", b: { id: 1, b: 2 } }, }; myFunction(obj, 'id') // [ ["" -> 1] ["d" -> "value"] ["d/b" -> 1] ]Estoy haciendo lo siguiente:
let **findAllByKey** = (obj, keyToFind) => Object.entries(obj).reduce( (acc, [key, value]) => key === keyToFind ? acc.concat(value) : typeof value === "object" ? acc.concat(findAllByKey(value, keyToFind)) : acc, [] ); console.log(findAllByKey(obj, "id"));Pero esto solo devuelve los valores, y tengo problemas para obtener la ruta: "/d/b", y dice que debe hacerse con un constructor de mapas ( New Map() ), pero con el mapa, no tengo ni idea. cómo hacerlo.
Puede obtener las entradas e iterar comprobando los valores.
const getPathes = (object, key) => Object .entries(object) .reduce((r, [k, v]) => { if (!v || typeof v !== 'object') return r; r.push(...getPathes(v, key).map(([l, v]) => [k + (l && '/') + l, v])); return r; }, key in object ? [['', object[key]]] : []), object = { id: 1, b: "value", c: 404, d: { id: "value", b: { id: 1, b: 2 } } }; console.log(getPathes(object, 'id')); // [["", 1], ["d", "value"], ["d/b" , 1]]Puede usar la biblioteca jsonpath .
Muestra:
const jp = require('jsonpath'); const result = jp.nodes(obj, '$..id');Resultado:
[ { path: [ '$', 'id' ], value: 1 }, { path: [ '$', 'd', 'id' ], value: 'value' }, { path: [ '$', 'd', 'b', 'id' ], value: 1 } ] Después de eso, obtiene objetos con propiedades de path y value y puede transformar el resultado como desee.