I am trying to create a function which must do the following:
takes a JavaScript object as first parameter
the object can have any structure and depth
takes a string containing a key as second parameter
returns a map with all values that are found for that key within the object o the key in the resulting map shall be the path to the key within the object where "/" is used as separator o the root key for the map is the name of the object
the result has to be something like:
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] ]
I am doing the following:
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"));
But this only returns the values, and I am having trouble to get the path: "/d/b", and it says It must be done with a map constructor ( New Map() ), but with map, I have no clue how to do it.
CodePudding user response:
You could get the entries and iterate by checking the values.
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]]
CodePudding user response:
You can use jsonpath library.
Sample:
const jp = require('jsonpath');
const result = jp.nodes(obj, '$..id');
Result:
[
{ path: [ '$', 'id' ], value: 1 },
{ path: [ '$', 'd', 'id' ], value: 'value' },
{ path: [ '$', 'd', 'b', 'id' ], value: 1 }
]
After that you get objects with path and value properties and can transform result as you want.
