0

I want to find object property dynamically from array that map to property location.

Example

 Var objectA = { a:{b:1} };
 Var Names = ['objectA','a','b'];

Howa can i get value of b by looping over array Names ?

Zalaboza
  • 8,899
  • 16
  • 77
  • 142
  • 1
    There's a similar question with the algorithm [here](http://stackoverflow.com/a/6491621/5743988). – 4castle Aug 30 '16 at 16:45
  • Why do you feel it's necessary to do this? It seems like an XY Problem to me. – zzzzBov Aug 30 '16 at 16:47
  • @zzzBov i hv a store singelron class, i want other classes to be able to listen for changes that happens on specicifc branch of its data, so i find it best to pass map to prorerty i need to listen to so bthat store emit update event when it changes. – Zalaboza Aug 30 '16 at 17:03

3 Answers3

2

Assuming objectA is available in the global scope (window.objectA), you could do something like this:

names.reduce(function (memo, value) {
    return memo[value]; 
}, window)

For any other "non-global" variable, you can create a getter function that takes the variable and the path (an array just like your names, but without the first value) as a parameter:

function nestedValue(obj, path) {
    return path.reduce(function (memo, value) {
         return memo[value];
    }, obj);
}

BTW, please note that Array.prototype.reduce() is a ES2015 feature, so if you need to be compatible with older browsers, you would have to use some variation of for loop for this task.

You could also check out lodash.get for more sophisticated solution (if you're willing to include it in your project).

mdziekon
  • 3,531
  • 3
  • 22
  • 32
1

You can use eval: eval(Names.join('.'))

Can use this with nodejs inside a sandbox:

const util = require('util');
const vm = require('vm');

const objectA = { a: { b: 1 }};
const Names = ['objectA', 'a', 'b'];

const sandbox = { objectA: objectA, Names: Names };
vm.createContext(sandbox);

for (var i = 0; i < 10; ++i) {
    vm.runInContext("var result = eval(Names.join('.'))", sandbox);
}
console.log(util.inspect(sandbox));

/* { 
     objectA: { a: { b: 1 } },
     Names: [ 'objectA', 'a', 'b' ],
     result: 1 
   }
*/
nitishagar
  • 9,038
  • 3
  • 28
  • 40
0

To do this without eval would require you store ObjectA as a property of another object that you could iterate over using the array keys. eval will work in this case though:

objectA = { a: { b: 1 }}
names = ['objectA', 'a', 'b']
alert(eval(names.join('.')))
Rob M.
  • 35,491
  • 6
  • 51
  • 50