繁体   English   中英

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

[英]How do I create a new JavaScript array without destroying the original array?

我似乎从来没有完全理解 JavaScript。 请向我解释这一点。

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

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 }
*/

这是因为数组和对象是引用类型。 因此,当您编辑参考时,则意味着所有对象都将被编辑。

所以尝试使用扩展运算符来创建全新的对象:

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

Object.assign

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

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

相反,只需在推送到arr2时创建对象的新实例,您就会纠正问题。

替换此行(将实例arr1推送到arr2

arr2.push(arr1[i]);

使用这一行(创建一个新实例并将其推送到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);

事情是当你修改这些值时,因为它们是引用,意味着它们是连接的,它们指向保存值的相同内存位置。 创建一个重复但独立的数组a2以便更改a1[k]不会导致a2[k]匹配修改后的a1[k]需要cloning

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

此链接将更深入地向您解释原因以及如何解决它。 如何在 JavaScript 中克隆数组

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM