如何在不破坏原始数组的情况下创建新的JavaScript数组?

时间:2019-12-20 11:28:18

标签: javascript arrays

我似乎从来没有完全理解JavaScript。请给我解释一下。

我有一个称为arr1的对象数组。在这个简化的示例中,它只有两个成员。名称和someValue。数组按名称排序,内容如下:

Harry   1
Joe     2
Joe     3
Peter   4

我想创建另一个名为arr2的数组。它应具有arr1中的唯一名称。如果找到重复项,则会为该名称添加someValue。我基本上希望将此作为arr2中的内容:

Harry   1
Joe     5 <-- the two values from Joe in arr1 sums up to 5
Peter   4

所以我想出了以下脚本。产生的arr2正是我想要的。 但是,arr1也已更新,这不是我想要的。

为什么会这样,我该如何解决?

var arr1 = [];
var arr2 = [];

arr1.push({name: 'Harry', someValue: 1});
arr1.push({name: 'Joe', someValue: 2});
arr1.push({name: 'Joe', someValue: 3});
arr1.push({name: 'Peter', someValue: 4});

let previousName = '';

for (var i=0;i<arr1.length;i++) {
  if (arr1[i].name == previousName) {
    arr2[arr2.length-1].someValue += arr1[i].someValue;
  } else {
    arr2.push(arr1[i]);
    previousName = arr1[i].name;
  }
}

/* Result arr1 is not ok:
0: Object { name: "Harry", someValue: 1 }
1: Object { name: "Joe", someValue: 5 } <-- I want the value 2 to be preserved
2: Object { name: "Joe", someValue: 3 }
3: Object { name: "Peter", someValue: 4 }

   Result arr2 is ok:
0: Object { name: "Harry", someValue: 1 }
1: Object { name: "Joe", someValue: 5 }
2: Object { name: "Peter", someValue: 4 }
*/

3 个答案:

答案 0 :(得分:3)

发生这种情况是因为数组和对象是引用类型。所以当你编辑 引用,则意味着将编辑所有对象。

因此,请尝试使用传播运算符创建全新的对象:

arr2.push({...arr1[i]});

Object.assign

arr2.push(Object.assign({}, arr1[i]));

答案 1 :(得分:3)

这是因为您要将对象实例arr1推到arr2而不是副本上。

相反,只需在推到arr2时创建对象的新实例,即可解决问题。

替换此行(将 instance arr1推送到arr2

arr2.push(arr1[i]);

此行(将创建一个新的 instance 并将其推送到arr2上:

arr2.push({name: arr1[i].name, someValue: arr1[i].someValue});

这是一个显示此内容的片段:

var arr1 = [];
var arr2 = [];

arr1.push({name: 'Harry', someValue: 1});
arr1.push({name: 'Joe', someValue: 2});
arr1.push({name: 'Joe', someValue: 3});
arr1.push({name: 'Peter', someValue: 4});
;
let previousName = '';

for (var i = 0; i < arr1.length; i++) {
  if (arr1[i].name == previousName) {
    arr2[arr2.length - 1].someValue += arr1[i].someValue;
  } else {
    arr2.push({name: arr1[i].name, someValue: arr1[i].someValue});
    previousName = arr1[i].name;
  }
}

console.log(arr1);
console.log(arr2);

答案 2 :(得分:2)

就是当您修改这些值时,因为它们是引用,表示它们已连接,它们指向保留该值的相同内存位置。创建重复但分开的数组a2,以使更改a1[k]不会导致a2[k]与修改后的a1[k]相匹配,需要克隆

可以使用简单的循环或切片来完成浅拷贝。 JSON.parseJSON.stringify创建深拷贝。

此链接将更深入地说明您的原因以及解决方法。 How to clone an array in JavaScript