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

accessing nested objects javascript
create nested array javascript
create nested json object in javascript dynamically
update nested object javascript
how to access array of objects in javascript
create a nested array recursively in javascript
javascript object with array property
iterate over nested objects javascript

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.

function assign(obj, keyPath, value) {
   lastKeyIndex = keyPath.length-1;
   for (var i = 0; i < lastKeyIndex; ++ i) {
     key = keyPath[i];
     if (!(key in obj)){
       obj[key] = {}
     }
     obj = obj[key];
   }
   obj[keyPath[lastKeyIndex]] = value;
}

Usage:

var settings = {};
assign(settings, ['Modules', 'Video', 'Plugin'], 'JWPlayer');

How do I build a nested object in Javascript dynamically , Say I have two arrays like so, const arr1 = ['a','b']; const arr2 = ['a… I want to iterate over the arrys and build a nested object that has this shape: I have given a bad example here with arr2 . you just create an empty object and then assign stuff to it, and use another if statement to check if there's a next  I have the following data. var data = "a.b.c.d"; //Just an example but can be more deep. A nested structure as a string to create a.b.c.n Now i want to create a js object from this data like thi

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.

How to create nested child objects in Javascript from array , The Object.assign in the original function (below) is unnecessary have noticed it Given the following list: +2 Beers for that function name! It exploits that objects are always passed by reference in JavaScript, even during assignment. while objects are created for all other missing properties. Use _. Even though you are using .on() with event delegation syntax, it is not working as the element to which the event is binded is created dynamically. You are registering the handler to col-md-1 which is the parent of the delete button, but that element also is created dynamically so when

My ES2015 solution. Keeps existing values.

const set = (obj, path, val) => { 
    const keys = path.split('.');
    const lastKey = keys.pop();
    const lastObj = keys.reduce((obj, key) => 
        obj[key] = obj[key] || {}, 
        obj); 
    lastObj[lastKey] = val;
};

Example:

const obj = {'a': {'prop': {'that': 'exists'}}};
set(obj, 'a.very.deep.prop', 'value');
console.log(JSON.stringify(obj));
// {"a":{"prop":{"that":"exists"},"very":{"deep":{"prop":"value"}}}}

Dynamically create array with nested objects/array, javascript typescript angular-2+ I also renamed x to length and y to height - these names are more descriptive, reputation to comment: you could also use arrays for rows instead of objects that have one property called "row". If you have only one value then maybe you don't need to wrap it in an object? Most of the time when you are getting undefined, the object/array simply doesn't have a property with that name. const foo = {bar: {baz: 42}}; console.log(foo.baz); // undefined Use console.log or console.dir and inspect the structure of object / array. The property you are trying to access might be actually defined on a nested object / array.

Another recursive solution:

var nest = function(obj, keys, v) {
    if (keys.length === 1) {
      obj[keys[0]] = v;
    } else {
      var key = keys.shift();
      obj[key] = nest(typeof obj[key] === 'undefined' ? {} : obj[key], keys, v);
    }

    return obj;
};

Example usage:

var dog = {bark: {sound: 'bark!'}};
nest(dog, ['bark', 'loudness'], 66);
nest(dog, ['woff', 'sound'], 'woff!');
console.log(dog); // {bark: {loudness: 66, sound: "bark!"}, woff: {sound: "woff!"}}

Nested Objects, Advance your JS skills in this free course by learning higher order functions, closures, Create nested data structures using objects; Access and iterate over data in a Now let's look at an example of an object with an array as the value: what the name of the key will be (meaning that the key will be dynamically created),  This might be trivial for smaller objects, but for thousands of records and possibly nested objects, this isn't right. Though you do create lesser code by reconstructing a new object, but not done right, you might end up eating more memory. If you don't dereference the other object properly, it may sit there and just eat up memory.

Using ES6 is shorten. Set your path into an array. first, you have to reverse the array, to start filling the object.

let obj = ['a','b','c'] // {a:{b:{c:{}}}
obj.reverse();

const nestedObject = obj.reduce((prev, current) => (
    {[current]:{...prev}}
), {});

Accessing Nested Objects in JavaScript, tldr; safely access nested objects in JavaScript in a super cool way. This is because we're trying to access name key from an object that does not exist. The usual You basically check if user exists, if not, you create an empty object on the fly. Unfortunately, you cannot access nested arrays with this trick  When to use Objects. JavaScript does not support associative arrays. You should use objects when you want the element names to be strings (text). You should use arrays when you want the element names to be numbers.

JavaScript object basics, Congratulations, you've reached the end of our first JS objects article — you should As with many things in JavaScript, creating an object often begins with this can be the name of a simple property, an item of an array property, used to set not only member values dynamically, but member names too. The this Keyword. In a function definition, this refers to the "owner" of the function. In the example above, this is the person object that "owns" the fullName function. In other words, this.firstName means the firstName property of this object.

Object initializer, Objects can be initialized using new Object(), Object.create(), or using Shorthand property names (ES2015) let a = 'foo', b = 42, c = {}; let o = {a, b, It copies own enumerable properties from a provided object onto a new object. In JSON the values can only be strings, numbers, arrays, true , false , null  Modern JavaScript has added a forEach method to the native array object. Array.prototype.forEach (callback ( [value, index, array]), thisArg) This method is a member of the array prototype and uses a callback function for you to embed any custom logic to the iteration.

Javascript dynamically access nested object property, Dynamically access object property using variable (8) I'm trying to access a property of objects of the given property name and property value using javascript. g. JavaScript - How To Create Nested How To Create Nested Objects Array In  In this article, we discuss three different ways to create objects in JavaScript, including using object literals, the new keyword, and classes. Three Ways to Create Objects in JavaScript - DZone

Comments
  • Well, I wrote pretty much that same thing, except that I was going to explain newSettingName.split('_'). I don't see the point behind duplicate answers, so there. Maybe explain better your answer though.
  • what exactly are keyPath and value in that function ?
  • Great one. I did go to last value and hence failed. Understood, searched and found this. Being at a parent level is key and works fine.
  • keyPath here for above example, means, the key is Modules.Video.Plugin, and value is JWPlayer, in the json they are trying to build
  • I hope you realize that you're answering a question for which the accepted answer is already over 15 months old...
  • @Bart: Shouldn't I ?
  • It's okay, it's just not very likely the person who asked the question is still looking for an answer. Your answer is still good (and different from the rest) so I gave you some thumbs up on it.
  • Actually, this is the best answer as it behaves as expected.
  • It's never too late to improve an existing answer.
  • Awesome! How can this be changed if nestedObject was defined previously and has {a: {b:{}} set, but not a.b.c. ? I.e. preserving existing keys and only add missing. That would be really useful.
  • Why on earth does this work and not delete existing nested objects?! You have blown minds, sir.
  • I know this is old, but thought I'd chime in. The reason this works is the "base" argument is passed by a copy of the reference to the original object. So on each iteration evaluated from right-to-left base becomes a pointer to the position of the currently assigned property.
  • Perfect. Thank you for this.