递归地将对象推入数组

时间:2017-10-03 22:41:13

标签: javascript arrays object

我有一个模板对象,我递归修改并需要像这样推入一个数组

[ { a: 7200, b: 1.13, c: 0, d: 800, e: 5, f: 5, g: 1, h: 1 },
{ a: 86400, b: 1.12, c: 0, d: 3200, e: 8, f: 8, g: 1, h: 1 } ]

预期输出为

[ { a: 86400, b: 1.11, c: 0, d: 3200, e: 8, f: 8, g: 1, h: 1 },
  { a: 86400, b: 1.11, c: 0, d: 3200, e: 8, f: 8, g: 1, h: 1 } ]

实际是

{{1}}

我发现当我操纵对象时,它会在每次将对象放入数组时递归更改值。

所以问题是,如何以递归更新基本模板时不会追溯更改所有值的方式将新对象放入此数组中。

(在预期的输出[1] .b中编辑了错误的值0.01)

4 个答案:

答案 0 :(得分:1)

您正在改变原始对象的值。您必须跟踪前一个对象,根据您要计算的值并推入数组。



var base = {
  a: 600,
  b: 1.15,
  c: 0,
  d: 200,
  e: 3,
  f: 3,
  g: 1,
  h: 1,
}
var array2 = [];
// store the reference of the original object
var prev = base;

for (var i = 1; i <= 3; i++) {
  var obj = {};
  // populate the data for the new object 
  // based on the previous object in array 
  obj.a = prev.a * 12;
  obj.b = prev.b - 0.01;
  obj.c = prev.c;
  obj.d = prev.d * 4;
  obj.e = Math.ceil(prev.e * 1.5);
  obj.f = prev.e;
  obj.g = prev.g;
  obj.h = prev.h;

  array2.push(obj);
  
  // save the reference of the current object state
  // to be used in the next iteration
  prev = obj;
}

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

答案 1 :(得分:0)

您只有一个对象,并且您正在推送该数组中的同一个对象。可以将此变量base视为指向存储在该数组中的对象的指针,这就是为什么,您的最后一次修改会显示在数组的所有元素中。

在将基础对象推送到数组之前,您需要的是基础对象的深层副本。

use lodash cloneDeep用于深层复制。

Object assign也可以帮助执行此操作,但请确保在使用之前阅读深度克隆警告。

答案 2 :(得分:0)

要展开Sushanth's answer,您还有其他选择。

(1)base函数而不是base对象:

function getBase() {
  return {
    a: 600,
    b: 1.15,
    c: 0,
    d: 200,
    e: 3,
    f: 3,
    g: 1,
    h: 1,
  };
}

var array2 = []; // You should use array literals instead of `new Array`
for(var i=1;i<=3;i++){
  var base = getBase();

  base.a = base.a*12
  base.b = base.b-0.01
  base.d = base.d*4
  base.e = Math.ceil(base.e * 1.5)
  base.f = base.e
  array2.push(base)
}

(2)Object.assign - 如果您在node4 +(或者至少是不支持IE11或更低版本的浏览器环境中),则可以使用此方法复制平面对象(无嵌套属性)。 Neeraj Sharma's answer触及了嵌套属性时该怎么做。

var _base = {
  a: 600,
  b: 1.15,
  c: 0,
  d: 200,
  e: 3,
  f: 3,
  g: 1,
  h: 1,
};

var array2 = []; // You should use array literals instead of `new Array`
for(var i=1;i<=3;i++){
  var base = Object.assign({}, _base);

  base.a = base.a*12
  base.b = base.b-0.01
  base.d = base.d*4
  base.e = Math.ceil(base.e * 1.5)
  base.f = base.e
  array2.push(base)
}

答案 3 :(得分:0)

以您为例,您要从相同引用中推送数组元素。 要推送来自不同引用的元素,您可以使用下面的提示行。无需深层复制。

array2.push(JSON.parse(JSON.stringify(base)));
相关问题