Convert array into nested object
Asked Answered
R

4

7

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

Rule answered 29/8, 2018 at 12:10 Comment(2)
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?Counterclaim
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. TksRule
C
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);
Counterclaim answered 29/8, 2018 at 12:15 Comment(4)
{[key]: res} --- has this always been a thing? [key]:value ?Airtight
Not always. Computed keys exist since ES2016 or so.Counterclaim
Bear in mind that keys.reverse will mutate the original array. Using keys.reduceRight (as suggested below) may be preferable.Spurt
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}) , {});Abixah
C
9

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

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

console.log(result);
Conners answered 29/8, 2018 at 16:16 Comment(0)
O
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']));
Outguard answered 29/8, 2018 at 12:15 Comment(1)
Worked as expected !! Thanks for your help!!Rule
I
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));
Intromission answered 28/4 at 13:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.