Skip to content Skip to sidebar Skip to footer

Automated Nested Objects

A couple of days ago I was having fun with some js, when I came to the question if I could automate object nesting. Of course I'm still a newby so I haven't gotten too far. But wha

Solution 1:

If i understand you correctly, you can do something like this:

var createNestedObjects = function( obj ) {
    //get all the passed arguments 
    var args = Array.prototype.slice.call(arguments);

    //start with i = 1, as we want to skip obj in the arguments
    for( var i = 1; i < args.length; i++ ) {
        obj = obj[ args[i] ] = obj[ args[i] ] || {};
    }

};

var a = {};
createNestedObjects( a, "b", "c", "d", "e", "f" );
a.b.c.d.e.f = "happy ending";
console.log(a.b.c.d.e.f); //logs "happy ending"

explanation line 3

Your requirement is to pass as many strings as required to the function to create any size of nested objects you would like. However, as you can see, the function only has one parameter: obj. The cool thing is that javascript allows you to pass even more parameters and you are still able to access them using the arguments object. The arguments object is available in all functions. The arguments object is similar to an array, but not quite the same as it is an object in it's own, if you log it in this case it will display:

Arguments [{}, "b", "c", "d", "e", "f"] (6) 

We can't loop through the agruments object using a for loop, so on line 3 it's converted to an array first. arguments object reference


explanation inside the loop

There are two interesting parts in this line. Javascript allows you to assign multiple variables at once as the assignment operator assigns a value to its left operand based on the value of its right operand

  var a, b;
  a =  b = 10; //both a and b are set to 10

Using || operator is used here to set a default value ( in this case {} )if the value on the left is undefined. Which is for example also handy to set default values

function setDelay ( delay ){

    delay = delay || 60
    return delay

}

setDelay(  ) //no parameter is passed, delay is set to 60 
setDelay( 120 ) 120 is passed and delay is set to 120

In this case the line

obj = obj[ args[i] ] = obj[ args[i] ] || {};

can be rewritten as:

var name = args[i];    // first loop args[i] is "b"    
if(!obj[name]){        // a.b does not exist       
    obj[name] = {};    // a.b is set to {}      
}
obj = obj[name];       // a is set to a.b 

which checks if there is already an object with that name, if not it's created and set as obj so we can nest objects in the next loop.

I hope this clarifies the code


Solution 2:

So, you want to convert values to a nested object? This can be done by doing something like this:

let values = ['b', 'c', 'd', 'e', 'f', 'g'];
let a = {};
// Every time we loop, we change the root
let root = a;

for (let value of values) {
  // Set root to the value of the array and assign a new object
  root = root[value] = {};
}
// Set the string
a.b.c.d.e.f.g = "Happy ending!";

console.log(a.b.c.d.e.f.g);
console.log(a);

It basically does this inside the loop:

a = a[b] = {};
a[b] = a[b][c] = {};
a[b][c] = a[b][c][d] = {};
a[b][c][d] = a[b][c][d][e] = {};
a[b][c][d][e] = a[b][c][d][e][f] = {};
a[b][c][d][e][f] = a[b][c][d][e][f][g] = {};

It creates a new key every loop and assigns an empty object to it. The next iteration creates a new key (with an empty object as value) inside the newly created object from the previous loop. This goes on until all values of the array have been assigned.


Post a Comment for "Automated Nested Objects"