Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript: how to dynamically create nested objects using object names given by an array

I hope someone can help me with this Javascript.

I have an Object called "Settings" and I would like to write a function that adds new settings to that object.

The new setting's name and value are provided as strings. The string giving the setting's name is then split by the underscores into an array. The new setting should get added to the existing "Settings" object by creating new nested objects with the names given by each part of the array, except the last part which should be a string giving the setting's value. I should then be able to refer to the setting and e.g. alert its value. I can do this in a static way like this...

var Settings = {}; var newSettingName = "Modules_Video_Plugin"; var newSettingValue = "JWPlayer"; var newSettingNameArray = newSettingName.split("_");  Settings[newSettingNameArray[0]] = {}; Settings[newSettingNameArray[0]][newSettingNameArray[1]] = {}; Settings[newSettingNameArray[0]][newSettingNameArray[1]][newSettingNameArray[2]] = newSettingValue;  alert(Settings.Modules.Mediaplayers.Video.Plugin); 

... the part that creates the nested objects is doing this ...

Settings["Modules"] = {}; Settings["Modules"]["Video"] = {}; Settings["Modules"]["Video"]["Plugin"] = "JWPlayer"; 

However, as the number of parts that make up the setting name can vary, e.g. a newSettingName could be "Modules_Floorplan_Image_Src", I'd like to do this dynamically using a function such as...

createSetting (newSettingNameArray, newSettingValue);  function createSetting(setting, value) {     // code to create new setting goes here } 

Can anyone help me work out how to do this dynamically?

I presume there has to be a for...loop in there to itterate through the array, but I haven't been able to work out a way to create the nested objects.

If you've got this far thanks very much for taking the time to read even if you can't help.

like image 749
David Avatar asked Mar 30 '11 09:03

David


People also ask

How do I create a nested object in JavaScript?

const obj = { code: "AA", sub: { code: "BB", sub: { code: "CC", sub: { code: "DD", sub: { code: "EE", sub: {} } } } } }; Notice that for each unique couple in the string we have a new sub object and the code property at any level represents a specific couple.

Can you nest objects in JavaScript?

You can create nested objects within a nested object. In the following example, Salary is an object that resides inside the main object named Employee . The dot notation can access the property of nested objects.

Can we add dynamically named properties to JavaScript object?

So the best way of adding dynamically created property is the [bracket] method. Show activity on this post. Example: ReadValue("object.


1 Answers

Put in a function, short and fast (no recursion).

var createNestedObject = function( base, names ) {     for( var i = 0; i < names.length; i++ ) {         base = base[ names[i] ] = base[ names[i] ] || {};     } };  // Usage: createNestedObject( window, ["shapes", "triangle", "points"] ); // Now window.shapes.triangle.points is an empty object, ready to be used. 

It skips already existing parts of the hierarchy. Useful if you are not sure whether the hierarchy was already created.

Or:

A fancier version where you can directly assign the value to the last object in the hierarchy, and you can chain function calls because it returns the last object.

// Function: createNestedObject( base, names[, value] ) //   base: the object on which to create the hierarchy //   names: an array of strings contaning the names of the objects //   value (optional): if given, will be the last object in the hierarchy // Returns: the last object in the hierarchy var createNestedObject = function( base, names, value ) {     // If a value is given, remove the last name and keep it for later:     var lastName = arguments.length === 3 ? names.pop() : false;      // Walk the hierarchy, creating new objects where needed.     // If the lastName was removed, then the last object is not set yet:     for( var i = 0; i < names.length; i++ ) {         base = base[ names[i] ] = base[ names[i] ] || {};     }      // If a value was given, set it to the last name:     if( lastName ) base = base[ lastName ] = value;      // Return the last object in the hierarchy:     return base; };  // Usages:  createNestedObject( window, ["shapes", "circle"] ); // Now window.shapes.circle is an empty object, ready to be used.  var obj = {}; // Works with any object other that window too createNestedObject( obj, ["shapes", "rectangle", "width"], 300 ); // Now we have: obj.shapes.rectangle.width === 300  createNestedObject( obj, "shapes.rectangle.height".split('.'), 400 ); // Now we have: obj.shapes.rectangle.height === 400 

Note: if your hierarchy needs to be built from values other that standard objects (ie. not {}), see also TimDog's answer below.

Edit: uses regular loops instead of for...in loops. It's safer in cases where a library modifies the Array prototype.

like image 73
jlgrall Avatar answered Sep 29 '22 17:09

jlgrall