-1

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?

2
  • 2
    Just use a loop? Commented Jul 22, 2019 at 19:55
  • Here's a solution that uses recursion: jsfiddle.net/khrismuc/jtk9L0ro Commented Jul 22, 2019 at 20:02

3 Answers 3

2

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.

Sign up to request clarification or add additional context in comments.

3 Comments

no need to pop in advance, the result is a function and the parentheses is the needed call. savind the last key is necessary for assigning a value to it.
@NinaScholz It's also necessary for calling the method as a method, with the object as the context. Otherwise, reduce returns a plain function that would be called with an undefined thisArg.
1

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

0

.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();

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.