javascript - 如何根据对象的特定值更新对象?
问题描述
我有 2 个对象,我想将值从一个对象“移植”到另一个对象。
我从中提取数据的第一个对象如下所示:
var userData = {
Data: [
{
Amount: 430140.68,
Year: "2015",
AccountName: "Account 1"
},
{
Amount: 458997.32,
Year: "2016",
Name: "Account 2"
},
]
}
我将数据放入的第二个对象如下所示:
[
{
"name": "Account 1",
"data": [
0,
0
],
},
{
"name": "Account 2",
"data": [
0,
0
],
}
]
我的目标是采用Amount
第一个对象的形式并将其放在第二个对象的data
数组中。每年对应于“数据”数组中的一个值。
因此,生成的更新对象应如下所示:
[
{
"name": "Account 1",
"data": [
430140.68,
0
],
},
{
"name": "Account 2",
"data": [
0,
458997.32
],
}
]
为了尝试实现这一点,我有以下代码:
const yearArrLength = yearsArr.length;
const generatedObj = new Array(yearArrLength).fill(0);
// Push name and populate data array with 0s.
for (var key of Object.keys(userData.Data)) {
var accName = userData.Data[key].AccountName;
if (!generatedObj.find(key => key.name === accName)){
generatedObj.push({'name': accName, 'data': blankDataArr});
}
}
for (var key of Object.keys(userData.Data)) {
var accName = userData.Data[key].AccountName;
var accAmount = userData.Data[key].Amount;
var accYear = userData.Data[key].Year;
// Get location of years array value
var yearArrIndex = yearsArr.indexOf(accYear);
for (var key of Object.keys(generatedObj)) {
if (generatedObj[key].name == accName) {
generatedObj[key].data[yearArrIndex] = accAmount;
}
}
}
但是,这似乎填充了所有数据数组值,例如:
[
{
"name": "Account 1",
"data": [
430140.68,
458997.32
],
},
{
"name": "Account 2",
"data": [
430140.68,
458997.32
],
}
]
我完全不知道为什么。该if
语句应该检查是否有匹配的帐户名称,但它似乎没有触发。
有谁知道我做错了什么?
解决方案
看起来您blankDataArr
每次都在推送完全相同的内容-您不是在推送新的阵列,而是在向所有人推送相同的阵列。
举一个更简单的例子:
const subarr = [];
const arr = [subarr, subarr];
arr[0].push('x');
console.log(JSON.stringify(arr));
// both items in `arr` have changed
// because both refer to the exact same subarr object
对于您正在尝试做的事情,看起来首先创建一个对象或 Map 索引会容易得多AccountName
,这样您只需AccountName
在迭代时访问或创建属性,然后分配给适当的年份。
const yearsArr = ['2015', '2016'];
const userData = {
Data: [
{
Amount: 430140.68,
Year: "2015",
AccountName: "Account 1"
},
{
Amount: 458997.32,
Year: "2016",
AccountName: "Account 2"
},
]
};
const dataByAccountName = new Map();
for (const { AccountName, Amount, Year } of userData.Data) {
if (!dataByAccountName.has(AccountName)) {
// Create an entirely new array:
dataByAccountName.set(AccountName, yearsArr.map(() => 0));
}
const index = yearsArr.indexOf(Year);
dataByAccountName.get(AccountName)[index] = Amount;
}
const result = [...dataByAccountName.entries()].map(([name, data]) => ({ name, data }));
console.log(result);