简体   繁体   中英

Javascript - nested loops and indexes

I am trying to build an array that should look like this :

[
 [{"name":"Mercury","index":0}],
 [{"name":"Mercury","index":1},{"name":"Venus","index":1}],
 [{"name":"Mercury","index":2},{"name":"Venus","index":2},{"name":"Earth","index":2}],
...
]

Each element is the concatenation of the previous and a new object, and all the indexes get updated to the latest value (eg Mercury's index is 0, then 1, etc.). I have tried to build this array using the following code :

var b = [];
var buffer = [];
var names = ["Mercury","Venus","Earth"]
for (k=0;k<3;k++){

    // This array is necessary because with real data there are multiple elements for each k
    var a = [{"name":names[k],"index":0}]; 

    buffer = buffer.concat(a);

    // This is where the index of all the elements currently in the 
    // buffer (should) get(s) updated to the current k 
    for (n=0;n<buffer.length;n++){
        buffer[n].index = k;
    }

    // Add the buffer to the final array
    b.push(buffer);

}
console.log(b);

The final array (b) printed out to the console has the right number of objects in each element, but all the indexes everywhere are equal to the last value of k (2). I don't understand why this is happening, and don't know how to fix it.

This is happening because every object in the inner array is actually the exact same object as the one stored in the previous outer array's entries - you're only storing references to the object, not copies. When you update the index in the object you're updating it everywhere.

To resolve this, you need to create new objects in each inner iteration, or use an object copying function such as ES6's Object.assign , jQuery's $.extend or Underscore's _.clone .

Here's a version that uses the first approach, and also uses two nested .map calls to produce both the inner (variable length) arrays and the outer array:

var names = ["Mercury","Venus","Earth"];

var b = names.map(function(_, index, a) {
    return a.slice(0, index + 1).map(function(name) {
        return {name: name, index: index};
    });
});

or in ES6:

var names = ["Mercury","Venus","Earth"];
var b = names.map((_, index, a) => a.slice(0, index + 1).map(name => ({name, index})));

Try this:

 var names = ["Mercury","Venus","Earth"]; var result = []; for (var i=0; i<names.length; i++){ var _temp = []; for(var j=0; j<=i; j++){ _temp.push({ name: names[j], index:i }); } result.push(_temp); } console.log(result) 

try this simple script:

var b = [];
var names = ["Mercury","Venus","Earth"];
for(var pos = 0; pos < names.length; pos++) {
    var current = [];
    for(var x = 0; x < pos+1; x++) {
        current.push({"name": names[x], "index": pos});
    }
    b.push(current);
}

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