I have an object of arbitrary depth, and a string (or array) containing the keys which have to be traversed to get to the value.
As far as I know, there's no method to get to the value directly:
var object = {
user: {name: 'bob'},
'user.name': 'error'
};
object['user.name']; // contains 'error'
And the usual:
object['user']['name'];
is not possible without doing some very dirty eval stuff, because you do not know how far you will need to traverse through the object beforehand.
So I think this is only solvable using a recursive function:
var object = {
company: {
users: [
{name:'alice',age:'20'},
{name:'bob',age:'22'},
{name:'eve',age:'30'},
]
}
};
lookup = function recurse(array,object) {
var next = (array.length) ? object[array.shift()] : object;
return (next instanceof Object && next[array[0]]) ? recurse(array,next) : next;
}
var search = 'company.users.0.name';
lookup(search.split('.'), object);
I think this works well enough, but would love some feedback.
Efficiency is important here, could I rewrite the function to shave of a few milliseconds somewhere? Are there any pitfalls, bugs or exceptional cases to consider?
loopup()
function: merely useobject.company.users[0].name
directly gives the same result! In the other hand, I don't see how it's related to the example you first show at the beginning of the question: what's the matter with the strange'user.name': 'error'
member? Sorry if I missed something obvious, but could you clarify? \$\endgroup\$function lookup(object, search) { try { return eval("object['" + search.replace(/\./g, "']['") + "']"); } catch(e) { return null; } }
\$\endgroup\$var a = {}; a["happy.birthday"] = true;
? \$\endgroup\$