首页 > 解决方案 > 如何根据对象的特定值更新对象?

问题描述

我有 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语句应该检查是否有匹配的帐户名称,但它似乎没有触发。

有谁知道我做错了什么?

标签: javascriptjquery

解决方案


看起来您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);


推荐阅读