i have very simple question assume bellow object
const x={a:{b:"b"},c:{b:"b"}}
1)I want a method to return all of keys in my nested object eg ["a","b","c"]
2)I want a method to return all paths of my specific key eg for b=>["a","c"]
using lodash we have method _.get(obj,path) that return object value by the path we pass to get method but what about times we haven't path or path is vague
bellow code solve problem somehow
const findPath = (ob, key) => {
const path = [];
const keyExists = (obj) => {
if (!obj || (typeof obj !== "object" && !Array.isArray(obj))) {
return false;
}
else if (obj.hasOwnProperty(key)) {
return true;
}
else if (Array.isArray(obj)) {
let parentKey = path.length ? path.pop() : "";
for (let i = 0; i < obj.length; i++) {
path.push(`${parentKey}[${i}]`);
const result = keyExists(obj[i], key);
if (result) {
return result;
}
path.pop();
}
}
else {
for (const k in obj) {
path.push(k);
const result = keyExists(obj[k], key);
if (result) {
return result;
}
path.pop();
}
}
return false;
};
keyExists(ob);
return path.join(".");
}
problems with above code are:1)is not clean 2)don't return all paths for example in x={a:{b:"b"},c:{b:"b"}} return just "a"
You could take a recursive approach and check if the key exists, then return this key, wrapped in a nested array or return the result of nested objects and map this with the actual key or return an empty array, which is no entry for a flat map.
const
findPathes = (object, key) => key in object
? [[key]]
: Object.entries(object).flatMap(([k, v]) => {
if (!v || typeof v !== 'object') return [];
const pathes = findPathes(v, key);
return pathes.length
? pathes.map(a => [k, ...a])
: [];
}),
data = { a: { b: "b" }, c: { b: "b" }, d: { e: { f: { g: "g" }, h: { b: 'b' } } } } ;
console.log(findPathes(data, 'b'));
.as-console-wrapper { max-height: 100% !important; top: 0; }