Reputation: 13
Example:
var someObject = {
'part1' : {
'name': 'Part 1',
'txt': 'example',
},
'part2' : {
'name': 'Part 2',
'size': '15',
'qty' : '60'
},
'part3' : [
{
'name': 'Part 3A',
'size': '10',
'qty' : '20'
}, {
'name': '[value]',
'size': '5',
'qty' : '20'
}, {
'name': 'Part 3C',
'size': '7.5',
'qty' : '20'
}
]};
I need a function to get the path of the object to the value "[value]"
which can be anywhere on the object
This object will be passed by the User, for this reason I will not know the structure of it.
something like:
getPath(obj, '[value]');
Upvotes: 1
Views: 2927
Reputation: 353
If you try this on the window
object you'll end up in trouble as it is self referential. Quick and easy way to get around this is to a depth check:
function getPath(obj, val, path, depth) {
if (!depth) depth = 0;
if (depth > 50) return '';
path = path || "";
var fullpath = "";
for (var b in obj) {
if (obj[b] === val) {
return (path + "/" + b);
}
else if (typeof obj[b] === "object") {
fullpath = getPath(obj[b], val, path + "/" + b, depth++) || fullpath;
}
}
return fullpath;
}
This will return the same kind of path as above:
/part3/2/qty
To make that into an actual reference to variable simply regex:
'window' + '/part3/2/qty'.replace(/\/([0-9]+)\//g, '[$1].').replace(/\//g, '.')
Upvotes: 0
Reputation: 26878
Here's some code that should get you a path to your object, not sure how super safe it is:
function getPath(obj, val, path) {
path = path || "";
var fullpath = "";
for (var b in obj) {
if (obj[b] === val) {
return (path + "/" + b);
}
else if (typeof obj[b] === "object") {
fullpath = getPath(obj[b], val, path + "/" + b) || fullpath;
}
}
return fullpath;
}
Where testObj
is the object in your example:
console.log(getPath(testObj, '20')); // Prints: /part3/2/qty
console.log(getPath(testObj, "[value]")); // Prints: /part3/1/name
Upvotes: 2
Reputation: 8646
Try this:
The method returns an object, that contains the parts.
function getPath(obj, value, path){
path = path || [];
if(obj instanceof Array || obj instanceof Object){
//Search within children
for(var i in obj){
path.push(i); //push path, will be pop() if no found
var subPath = getPath(obj[i], value, path);
//We found nothing in children
if(subPath instanceof Array){
if(subPath.length == 1 && subPath[0]==i){
path.pop();
}
//We found something in children
}else if(subPath instanceof Object){
path = subPath;
break;
}
}
}else{
//Match ?
if(obj == value){
return {finalPath:path};
}else{
//not ->backtrack
path.pop();
return false;
}
}
return path;
}
Maybe its not the best code, took me 10min there but it should work.
To see any result, check your dev console F12.
Upvotes: 0