Reputation: 18932
Suppose I have this:
var a = { A : { AA : 1 }, B : 2 };
Is there a way for me to create a variable that could allow me to reference either AA or B? What would the syntax look like?
// I know I can do this:
a['B']; // 2
a['A']['AA']; // 1
// something like this?
var myRef = ???;
a[myRef]; 1 or 2 depending on myRef
If not, what's a better way to get what I'm going for here?
Upvotes: 21
Views: 19885
Reputation: 11253
With lodash _.get function, you can access nested properties with dot syntax.
Node server-side example:
const _ = require('lodash');
let item = { a: {b:'AA'}};
_.get(item, 'a.b');
Upvotes: 2
Reputation: 391
Since i also encounter this problem, i wrote also a one line util for this (ES6):
const leaf = (obj, path) => (path.split('.').reduce((value,el) => value[el], obj))
Example:
const objSample = { owner: { name: 'Neo' } };
const pathSample = 'owner.name';
leaf(objSample, pathSample) //'Neo'
Upvotes: 16
Reputation: 11552
Not directly.
Flatten object, to have new object var a = { 'A.AA' : 1; B : 2 };
.
See compressing object hierarchies in JavaScript or Flattening a complex json object for mvc binding to get the javascript function for it.
I can see it was already addressed by Eugen. Reposted code-reviewed version:
function Leaf(obj,path) {
path=path.split('.');
var res=obj;
for (var i=0;i<path.length;i++) res=res[path[i]];
return res;
}
var x = eval("a." + myRef); // x will be 1 for myRef == "A.AA", 2 for "B"
Be careful with this solution as you may introduce some security issues. It is more of the curiosity.
Upvotes: 35
Reputation: 65342
function Leaf(obj,path) {
path=path.split('.');
var res=obj;
for (var i=0;i<path.length;i++) obj=obj[path[i]];
return res;
}
Leaf(a,'B')=2
Leaf(a,'A.AA')=1
Decorate with error handling etc. according to your needs.
Upvotes: 3
Reputation: 4345
Actually no, because js object are seen as property bags and doing a[X]
is for accessing first level properties only...
But you could wrap the logic a['A']['AA']; // 1
in a function that does the same, like this
//WARN... no undefined check here => todo !
function _(o, path) {
var tmp = o
for (var i=0 ; i < path.length ; i++) {
tmp = tmp[path[i]]
}
return tmp
}
var r = _(a, ['A', 'AA'])
This is pretty much the same as other answers, but the difference is when dummy boy create object property name containing dots... Like var a = {"a.a" : 3 }
is valid.
Now, such problem would occurs maybe more often now with the help of IndexedDB to store anything locally...
Upvotes: 1