问题
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 what I got is this:
var a = {};
var stso = ""; storing the second object
function sto(b) { // start the object
a[b] = {};
stso = b;
}
function nmo(...objs) { // nesting more object
console.log(objs[0]);
if(objs.length) { // checking to see that I have at least one variable before proceding
for(i = 0; i < objs.length; i++) { // looping through arguments
a[stso][objs[i]] = {}; // and now I would have to repeat one more more for lever for every argument, meaning, the deeper I want to go into the object, the more nested for loops I have to make.
}
}
}
sto("b");
nmo("c");
a.b.c = "Happy ending!";
console.log(a.b.c); // It seems we still dont have a happy ending
// and as a second example
sto("b");
nmo("c", "d", "e", "f", "g");
a.b.c.d.e.f.g = "Another happy ending!";
console.log(a.b.c.d.e.f.g); // Our second happy ending was also unhappy...
In summary, you define the second object in one function, you define as many objects as you want in your second function in order.
How could I achieve this with my current structure?
回答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
回答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.
来源:https://stackoverflow.com/questions/37356622/automated-nested-objects