Let's say I've got the following javascript object
var obj = {
a:{
b:"value",
c:{
d:"value2"
}
}
}
What function would, when input with the "d" object (for example, function getPath(obj, d)
), output the "a.c.d" string? I've tried various things including object-path, but it doesn't seem to be designed for that
You could use an iterative and recursive approach.
function getPath(object, key) {
function iter(o, p) {
if (typeof o === 'object') {
return Object.keys(o).some(function (k) {
return iter(o[k], p.concat(k));
});
}
if (p[p.length - 1] === key) {
path = p;
return true;
}
}
var path = [];
iter(object, []);
return path.join('.');
}
console.log(getPath({ d: { d: { d: { d: 'val' } } } }, 'd'));
console.log(getPath({ a: { b: 'value', c: { d: 'value2' } } }, 'd'));
.as-console-wrapper { max-height: 100% !important; top: 0; }
I had a fair amount of fun making this one up, it generates a list of every possible path that can be made from the object and returns the longest one ending with the correct key, it returns an empty string of not found:
function getPath(obj, key) {
paths = []
function getPaths(obj, path) {
if (obj instanceof Object && !(obj instanceof Array)) {
for (var k in obj){
paths.push(path + "." + k)
getPaths(obj[k], path + "." + k)
}
}
}
getPaths(obj, "")
return paths.map(function(p) {
return p.slice(p.lastIndexOf(".") + 1) == key ? p.slice(1) : ''
}).sort(function(a, b) {return b.split(".").length - a.split(".").length;})[0];
}
var obj = { a:{ b:"value", c:{ d:"value2"}}};
console.log(getPath(obj, "b"))
console.log(getPath(obj, "c"))
console.log(getPath(obj, "d"))
var obj = { d:{ d:"value", d:{ d:"value2"}}};
console.log(getPath(obj, "d"))
You can iterate over the object using a recursive function, and save the path like :
function getPath(object, keyValue, path) {
for (var k in object) {
if (k === keyValue) {
return path + '.' + k;
}
else if (typeof object[k] === 'object') {
return getPath(object[k], keyValue, path !== '' ? path + '.' + k : k);
}
}
}
var obj = {
a:{
b:"value",
c:{
d:"value2"
}
}
};
var path = getPath(obj, 'd', '');
console.log(path);
Here you go. The function you want to use is findLongestPath
:
var obj = {
a:{
b:"value",
c:{
d:"value2"
}
}
};
function findAllPaths(obj, property, startString = '') {
var pathStrings = [];
Object.keys(obj).forEach(key => {
if(typeof obj[key] === 'object') {
pathStrings.push(...findAllPaths(obj[key], property, startString + key + '.'));
return;
}
pathStrings.push(startString + key);
});
return pathStrings;
}
function findLongestPath(obj, property) {
return findAllPaths(obj, property)
.filter(str => str.split('').reverse().join('').slice(0, property.length) === property.split('').reverse().join(''))
.reduce((longest, next) => longest.length >= next.length ? longest : next, '');
}
console.log(findLongestPath(obj, 'd'));
findAllPaths
is a recursive function that iterates through the object and generates an array of all possible object paths. findLongestPath
filters those strings to make sure the last property matches the property given, and then returns the longest of those.