简体   繁体   中英

Create a dynamic nested object from array of properties

This sounds like a simple task, but I can't quite figure it out: I have an array :

var array = ['opt1','sub1','subsub1','subsubsub1']

From that I want to generate the following objects:

{
  opt1:{
    sub1:{
      subsub1:{
        subsubsub1:{}
      }
    }
  }
}

I have a way to do it, making a string and using eval, but I'm looking to avoid that, any idea?

You could use reduce :

 var array = ['opt1','sub1','subsub1','subsubsub1']; var object = {}; array.reduce(function(o, s) { return o[s] = {}; }, object); console.log(object);

But this was only introduced in ECMAScript 5.1, so it won't be supported in some older browsers. If you want something that will be supported by legacy browsers, you could use the polyfill technique described in the MDN article above, or a simple for -loop, like this:

 var array = ['opt1','sub1','subsub1','subsubsub1']; var object = {}, o = object; for(var i = 0; i < array.length; i++) { o = o[array[i]] = {}; } console.log(object);

You can use reduceRight to transform the array into a 'chain' of objects:

 const array = ['a', 'b', 'c']; const object = array.reduceRight((obj, next) => ({[next]: obj}), {}); // Example: console.log(object); // {"a":{"b":{"c":{}}}}

you could use lodash set function

_.set(yourObject, 'a.b.c')

You can use the following Function

function arr2nestedObject(myArray){
 var cp_myArray = myArray;
 var lastobj = {};
 while(cp_myArray.length>0){
    newobj = {};
    var prop = cp_myArray.pop();
    newobj[prop] = lastobj;
    lastobj = newobj;
 }
 return lastobj;
}

The following code:

var myArray = ["personal-information", "address", "street",'Great-Success'];
console.log(JSON.stringify(arr2nestedObject(myArray),undefined,2));

Would Produce the Following Output:

{
  "personal-information": {
   "address": {
    "street": {
     "Great-Success": {}
     }
    }
  }
}
Please let me know if that was what you meant.

Kind Regards.

As @pswg answer is a very good answer with pure js, but if you want an alternative with in a descriptive and functional way of that and set a value for final nested prop , you can use ramdajs assocPath https://ramdajs.com/docs/#assocPath like below:

var array = ['opt1','sub1','subsub1','subsubsub1'];

R.assocPath(array, "the value", {}); 

在此处输入图片说明

more details:

Makes a shallow clone of an object, setting or overriding the nodes required to create the given path, and placing the specific value at the tail end of that path. Note that this copies and flattens prototype properties onto the new object as well. All non-primitive properties are copied by reference.

examples:

R.assocPath(['a', 'b', 'c'], 42, {a: {b: {c: 0}}}); //=> {a: {b: {c: 42}}}

// Any missing or non-object keys in path will be overridden
R.assocPath(['a', 'b', 'c'], 42, {a: 5}); //=> {a: {b: {c: 42}}}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM