i have arrays like this: ['req','changepage'] or like this: ['dashboard','draw','ovreview']
the result i need is:
mainObject.req.changepage()
and
mainObject.dashboard.draw.overview()
I know that i can do:
mainObject.[array[0]].[array[1]]()
but the length of the array may vary... how to do that programatically?
-
2Just use a loop?Bergi– Bergi2019年07月22日 19:55:34 +00:00Commented Jul 22, 2019 at 19:55
-
Here's a solution that uses recursion: jsfiddle.net/khrismuc/jtk9L0rouser5734311– user57343112019年07月22日 20:02:03 +00:00Commented Jul 22, 2019 at 20:02
3 Answers 3
You can trivially access a property using reduce:
array.reduce((o, p) => o[p], mainObject)
but to make a method call on the right context object, you need to spare the last property access:
const methodname = array.pop();
array.reduce((o, p) => o[p], mainObject)[methodname]();
Alternatively, use slice if you don't want to mutate the array.
3 Comments
this keyword in the method doesn't work reduce returns a plain function that would be called with an undefined thisArg.Besides, Array.reduce, you could just use a loop.
let path = ['first', 'second', 'method'];
let target = {
first: {
second: {
value: 'success',
method: function(msg) {
console.log(msg + this.value);
}
}}};
let result = target;
for (let key of path.slice(0, -1)) {
result = result[key];
}
result[path.slice(-1)]('result: ') // prints 'result: success'
As Bergi alludes to in their answer, the Array.slice calls (or a use of Array.pop) are needed if the function being called might ever reference this. In my example above, if you just use let key of path, then call result('result: '), the output will be result: undefined.
Comments
.reduce is useful for that:
array.reduce((acc, key) => acc[key], mainObject)();
Or written using a plain for loop:
let acc = mainObject;
for(const key of array)
acc = acc[key];
acc();