Как обновить объект на основе определенного значения объекта?

#javascript #jquery

Вопрос:

У меня есть 2 объекта, и я хочу «пересадить» значения из одного объекта в другой.

Первый объект, из которого я черпаю данные, выглядит так:

 var userData = {  Data: [  {  Amount: 430140.68,  Year: "2015",  AccountName: "Account 1"  },  {  Amount: 458997.32,  Year: "2016",  Name: "Account 2"  },  ] }  

2-й объект, в который я помещаю данные, выглядит так:

 [  {  "name": "Account 1",  "data": [  0,  0  ],  },  {  "name": "Account 2",  "data": [  0,  0  ],  } ]  

Моя цель состоит в том, чтобы принять Amount форму первого объекта и поместить его в data массив 2-го. Каждый год соответствует значению в массиве «данные».

Таким образом, полученный обновленный объект должен выглядеть следующим образом:

 [  {  "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 =gt; 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;  }  }  }  

However, this seems to populate all of the data array values, eg:

 [  {  "name": "Account 1",  "data": [  430140.68,  458997.32  ],  },  {  "name": "Account 2",  "data": [  430140.68,  458997.32  ],  } ]  

Я совершенно не понимаю, почему. В if заявлении следует проверить, есть ли совпадающее имя учетной записи, но, похоже, оно не срабатывает.

Кто-нибудь знает, что я сделал не так?

Ответ №1:

Похоже 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 

Для того, что вы пытаетесь сделать, похоже, что было бы намного проще сначала индексировать объект или карту 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(() =gt; 0));  }  const index = yearsArr.indexOf(Year);  dataByAccountName.get(AccountName)[index] = Amount; } const result = [...dataByAccountName.entries()].map(([name, data]) =gt; ({ name, data })); console.log(result); 

Комментарии:

1. Большое спасибо! Извините, я совсем не силен в ES6. Как бы я добавил больше (статических) данных в новый объект? Например: Мне нужно добавить "type": "bar" к каждому. Я попробовал несколько способов, но не смог понять этого.

2. Не могу сказать наверняка, не зная точно, какого рода данные, но, возможно, вам просто нужно добавить свойство или несколько к объекту, возвращенному в финале .map ? ({ name, data }) к ({ name, data, someOtherProp }) или ({ name, data, type: 'bar' })