8

Let's say I have the following array: ['product' , 'model', 'version']

And I would like to have an object such as:

{
    product: { 
        model: { 
            version: { 

            }
        }
     }
}

However, that array is dynamic so it could have 2, 3 or fewer more items. How can this be achieved in the most efficient way?

Thanks

2
  • 1
    Do you need to create just exactly this empty object? Or do you need to merge those keys into an existing objects also containing other keys? Commented Aug 29, 2018 at 12:12
  • It can be anything in the value for now as I got access to the data I need to add to this object, but it needs to be within this structure. Tks Commented Aug 29, 2018 at 12:13

4 Answers 4

16

Just turn it inside out and successively wrap an inner object into an outer object:

const keys = ['product', 'model', 'version'];
const result = keys.reverse().reduce((res, key) => ({[key]: res}), {});
//                                   innermost value to start with ^^

console.log(result);

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

4 Comments

{[key]: res} --- has this always been a thing? [key]:value ?
Not always. Computed keys exist since ES2016 or so.
Bear in mind that keys.reverse will mutate the original array. Using keys.reduceRight (as suggested below) may be preferable.
If you want the final "leaf" of your object tree to contain a value other than an empty object, you can use a ternary keys.reduceRight((res, key, i) => (i === keys.length - 1 ? {[key]: myValue} : {[key]: res}) , {});
10

You can also do it with Array.prototype.reduceRight:

const result = ['product','model','version'].reduceRight((all, item) => ({[item]: all}), {});

console.log(result);

Comments

2

If I understood request correctly, this code might do what you need:

function convert(namesArray) {
  let result = {};
  let nestedObj = result;
  namesArray.forEach(name => {
    nestedObj[name] = {};
    nestedObj = nestedObj[name];
  });

  return result;
}


console.log(convert(['a', 'b', 'c']));

1 Comment

Worked as expected !! Thanks for your help!!
0
function convert(namesArray, val) {
  let result = {};
  let nestedObj = result;
  namesArray.forEach((name, index) => {
    nestedObj[name] = index === namesArray.length - 1 ? val : {};
    
    nestedObj = nestedObj[name];
  });

  return result;
}
console.log(convert(["a", "b", "c"], 3));

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.