Javascript - 嵌套循环和索引

时间:2016-01-18 13:51:30

标签: javascript arrays

我正在尝试构建一个看起来像这样的数组:

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

每个元素是前一个和新对象的串联,并且所有索引都更新为最新值(例如Mercury的索引是0,然后是1,等等)。 我尝试使用以下代码构建此数组:

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);

打印到控制台的最后一个数组(b)在每个元素中具有正确数量的对象,但是所有索引都等于k(2)的最后一个值。 我不明白为什么会这样,并且不知道如何修复它。

3 个答案:

答案 0 :(得分:4)

这种情况正在发生,因为内部数组中的每个对象实际上都是与前一个外部数组条目中存储的对象完全相同的对象 - 您只将引用存储到对象中,而不是副本。当您更新对象中的index时,您将在任何地方更新它。

要解决此问题,您需要在每个内部迭代中创建新对象,或者使用对象复制功能,例如ES6的Object.assign,jQuery的$.extend或Underscore的_.clone

这是一个使用第一种方法的版本,并且还使用两个嵌套的.map调用来生成内部(可变长度)数组和外部数组:

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};
    });
});

或在ES6中:

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

答案 1 :(得分:0)

试试这个:

&#13;
&#13;
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)
&#13;
&#13;
&#13;

答案 2 :(得分:0)

尝试这个简单的脚本:

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);
}