The following code prints the path of the key searched by its value inside an object:
function findKeyPath(obj, keyAttr, keyValue) {
let path = "";
(function findKey (obj, keyAttr, keyValue, keyPath) {
const prevPath = `${keyPath ? keyPath + "." : ""}`;
if (obj[keyAttr] === keyValue) {
path = `${prevPath}${keyAttr}`;
} else if (typeof obj === "object" && JSON.stringify(obj) === JSON.stringify(keyValue)) {
path = prevPath.slice(0, -1); // remove last dot
}
if (typeof obj === "object" && !Array.isArray(obj)) {
for (const key in obj) {
if (Array.isArray(obj[key])) {
for (let j = 0; j < obj[key].length; j++) {
findKey(obj[key][j], keyAttr, keyValue, `${prevPath}${key}[${j}]`);
}
}
if (obj[key] !== null && typeof obj[key] === "object") {
findKey(obj[key], keyAttr, keyValue, `${prevPath}${key}`);
}
}
}
}(obj, keyAttr, keyValue));
return path;
}
console.log(
findKeyPath({
users: [
{ name: "sam", surname: "red", age: 12 },
{ name: "sam", surname: "red", age: 42 },
{ name: "sam", surname: "red", age: 16 }
]
}, "age", 16)
);
... it prints users[2].age.
Trying to taking out the inner function, like this:
function findKey(obj, keyAttr, keyValue, keyPath) {
const prevPath = `${keyPath ? keyPath + "." : ""}`;
if (obj[keyAttr] === keyValue) {
return `${prevPath}${keyAttr}`;
} else if (typeof obj === "object" && JSON.stringify(obj) === JSON.stringify(keyValue)) {
return prevPath.slice(0, -1); // remove last dot
}
if (typeof obj === "object" && !Array.isArray(obj)) {
for (const key in obj) {
if (Array.isArray(obj[key])) {
for (let j = 0; j < obj[key].length; j++) {
findKey(obj[key][j], keyAttr, keyValue, `${prevPath}${key}[${j}]`);
}
}
if (obj[key] !== null && typeof obj[key] === "object") {
findKey(obj[key], keyAttr, keyValue, `${prevPath}${key}`);
}
}
}
}
console.log(
findKey({
users: [
{ name: "sam", surname: "red", age: 12 },
{ name: "sam", surname: "red", age: 42 },
{ name: "sam", surname: "red", age: 16 }
]
}, "age", 16)
);
It prints undefined. How can I solve it?
UPDATE, now it works:
function findKey(obj, keyAttr, keyValue, keyPath) {
const prevPath = `${keyPath ? keyPath + "." : ""}`;
let path = "";
if (obj[keyAttr] === keyValue) {
return `${prevPath}${keyAttr}`;
} else if (typeof obj === "object" && JSON.stringify(obj) === JSON.stringify(keyValue)) {
return prevPath.slice(0, -1); // remove last dot
}
if (typeof obj === "object" && !Array.isArray(obj)) {
for (const key in obj) {
if (Array.isArray(obj[key])) {
for (let j = 0; j < obj[key].length; j++) {
path = path.concat(findKey(obj[key][j], keyAttr, keyValue, `${prevPath}${key}[${j}]`));
}
}
if (obj[key] !== null && typeof obj[key] === "object") {
return path.concat(findKey(obj[key], keyAttr, keyValue, `${prevPath}${key}`));
}
}
}
return path;
}