通过for循环扩充数组只保留最后一个对象?

时间:2018-05-03 12:35:07

标签: javascript arrays for-loop

鉴于核心数据如下:

var data = [
    { name: "Student01", type: "received", grades: [ 12,12, 17, 17, 14.5, 10, 16, 15.5, 15.5, 15 ] },
    { name: "Student02", type: "given", grades: [ 11,6,15, 12 ] },
    { name: "Student03", type: "received", grades: [ 12,12, 17, 17, 14.5, 10, 16, 15.5, 15.5, 15 ]  },
    { name: "Student04", type: "given", grades: [ 12,8,13, 12 ] }
];

鉴于我应该尊重的模板对象

var template = {
  text: "Hello guys !",
  side: "negative",
  name: "Some student",
  x: [ 12.65, 17.92, 16.45 ],
  orientation: "h"
};

然后我建立了一个 augmentedData via for循环

var augmentedData = [];
for (var i=0; i<data.length;i++){
    var trace = template, 
         student = data[i];
    trace.text = "Step "+i;
    trace.name = student.name;
    trace.x    = student.grades;
    console.log(student, student.type)
    trace.side = student.type == "given"?"negative":"positive";
    console.log(vizGrades[i].type, trace, trace.side)
    augmentedData.push(trace);
}

我的最终增强数据由最后一个对象的4倍组成,自身增加了:

console.log(JSON.stringify(augmentedData));

返回:

[
  {"text":"Step 3","side":"negative","name":"Student04","x":[12,8,13,12],"orientation":"h"},
  {"text":"Step 3","side":"negative","name":"Student04","x":[12,8,13,12],"orientation":"h"},
  {"text":"Step 3","side":"negative","name":"Student04","x":[12,8,13,12],"orientation":"h"},
  {"text":"Step 3","side":"negative","name":"Student04","x":[12,8,13,12],"orientation":"h"}
];

出了什么问题?如何解决?

编辑:预期输出:

[
  {"text":"Step 0","side":"positive","name":"Student01","x":[12,12, 17, 17, 14.5, 10, 16, 15.5, 15.5, 15],"orientation":"h"},
  {"text":"Step 1","side":"negative","name":"Student02","x":[11,6,15, 12],"orientation":"h"},
  {"text":"Step 2","side":"positive","name":"Student03","x":[12,12, 17, 17, 14.5, 10, 16, 15.5, 15.5, 15],"orientation":"h"},
  {"text":"Step 3","side":"negative","name":"Student04","x":[12,8,13,12],"orientation":"h"}
];

5 个答案:

答案 0 :(得分:2)

  

出了什么问题?如何解决?

通过撰写var trace = template,您只向template对象声明引用。在修改trace对象时,template也将被修改。

您需要为template对象提供深层副本。为此,您可以使用Object.assign方法。

工作示例。

var data = [
    { name: "Student01", type: "received", grades: [ 12,12, 17, 17, 14.5, 10, 16, 15.5, 15.5, 15 ] },
    { name: "Student02", type: "given", grades: [ 11,6,15, 12 ] },
    { name: "Student03", type: "received", grades: [ 12,12, 17, 17, 14.5, 10, 16, 15.5, 15.5, 15 ]  },
    { name: "Student04", type: "given", grades: [ 12,8,13, 12 ] }
];

var template = {
  text: "Hello guys !",
  side: "negative",
  name: "Some student",
  x: [ 12.65, 17.92, 16.45 ],
  orientation: "h"
};

var augmentedData = [];
for (var i=0; i<data.length;i++){
    var trace = Object.assign({}, template), 
    student = data[i];
    trace.text = "Step "+i;
    trace.name = student.name;
    trace.x    = student.grades;
    console.log(student, student.type)
    trace.side = student.type == "given"?"negative":"positive";
    augmentedData.push(trace);
}
console.log(JSON.stringify(augmentedData));

您可以通过传递回调函数来使用map方法,以便为您的需求编写更简洁的解决方案。

另外,创建一个名为template的对象构造函数

var data = [
    { name: "Student01", type: "received", grades: [ 12,12, 17, 17, 14.5, 10, 16, 15.5, 15.5, 15 ] },
    { name: "Student02", type: "given", grades: [ 11,6,15, 12 ] },
    { name: "Student03", type: "received", grades: [ 12,12, 17, 17, 14.5, 10, 16, 15.5, 15.5, 15 ]  },
    { name: "Student04", type: "given", grades: [ 12,8,13, 12 ] }
];
function template(text, side, name, x) {
    this.text = text;
    this.side = side;
    this.name = name;
    this.x = x;
    this.orientation = "h";
}

const augmentedData = data.map((student, i) => 
   new template(`Step ${i}`, student.name, student.grades, student.type === "given" ? "negative" : "positive")
);
console.log(augmentedData);

答案 1 :(得分:2)

trace = template行只传递对模板中跟踪的引用,因此您在循环中一直使用同一个对象。

尝试

var template = function() {
  return {
    text: "Hello guys !",
    side: "negative",
    name: "Some student",
    x: [ 12.65, 17.92, 16.45 ],
    orientation: "h"
  };
}

因此trace每次使用trace = template();

时都会成为新对象

Fiddle

答案 2 :(得分:1)

目前,我们每次迭代都引用相同的对象并创建同一对象的数组。为了防止这种情况,我们需要将template对象的内容复制到trace对象中。

您可以使用浅色副本完成此操作。在Javascript中有几种方法可以生成浅层副本我使用了扩展运算符(var trace = {...template})将新模板复制到跟踪中。

var data = [
    { name: "Student01", type: "received", grades: [ 12,12, 17, 17, 14.5, 10, 16, 15.5, 15.5, 15 ] },
    { name: "Student02", type: "given", grades: [ 11,6,15, 12 ] },
    { name: "Student03", type: "received", grades: [ 12,12, 17, 17, 14.5, 10, 16, 15.5, 15.5, 15 ]  },
    { name: "Student04", type: "given", grades: [ 12,8,13, 12 ] }
];

var template = {
  text: "Hello guys !",
  side: "negative",
  name: "Some student",
  x: [ 12.65, 17.92, 16.45 ],
  orientation: "h"
};

var augmentedData = [];
for (var i=0; i<data.length;i++){
    var trace = {...template}, 
         student = data[i];
    trace.text = "Step "+i;
    trace.name = student.name;
    trace.x    = student.grades;
    trace.side = student.type == "given"?"negative":"positive";

    augmentedData.push(trace);
}

console.log(JSON.stringify(augmentedData));

答案 3 :(得分:1)

执行var trace = template时,您只是创建一个包含对相同对象的引用的新变量。

您应该每次创建一个新对象,而不是创建名为template的对象:

var data = [
    { name: "Student01", type: "received", grades: [ 12,12, 17, 17, 14.5, 10, 16, 15.5, 15.5, 15 ] },
    { name: "Student02", type: "given", grades: [ 11,6,15, 12 ] },
    { name: "Student03", type: "received", grades: [ 12,12, 17, 17, 14.5, 10, 16, 15.5, 15.5, 15 ]  },
    { name: "Student04", type: "given", grades: [ 12,8,13, 12 ] }
];

var augmentedData = [];
for (var i = 0; i < data.length; i++){
    var student = data[i];

    var trace = {
      text: "Step " + i,
      side: student.type == "given" ? "negative" : "positive",
      name: student.name,
      x: student.grades,
      orientation: "h"
    };

    augmentedData.push(trace);
}

console.log(JSON.stringify(augmentedData));

答案 4 :(得分:0)

您的trace变量是template对象的引用,因此每当您更改trace的某些属性时,它也会在引用的对象中发生更改(template)。

避免此问题的一种方法是将代码重写为map操作。这是地图的完美用例。

它看起来像这样:

&#13;
&#13;
const data = [
    { name: "Student01", type: "received", grades: [ 12,12, 17, 17, 14.5, 10, 16, 15.5, 15.5, 15 ] },
    { name: "Student02", type: "given", grades: [ 11,6,15, 12 ] },
    { name: "Student03", type: "received", grades: [ 12,12, 17, 17, 14.5, 10, 16, 15.5, 15.5, 15 ]  },
    { name: "Student04", type: "given", grades: [ 12,8,13, 12 ] }
];

const augmentedData = data.map((student, i) => ({
  text: `Step ${i}`,
  name: student.name,
  x: student.grades,
  side: student.type === "given" ? "negative" : "positive",
}));

console.log(augmentedData);
&#13;
&#13;
&#13;