0

I have 2 objects and I want to 'transplant' values from one object into the other.

The first object I am drawing data from looks like:

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

The 2nd object I am placing data into looks like:

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

My goal is to take the Amount form the first object and place it in the data array of the 2nd. Each year corresponds to a value in the 'data` array.

So, the resulting updated object should look like:

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

To try to achieve this I have the following code:

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;
        }
    }

}

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
        ],
    }
]

I'm completely stumped as to why. The if statement should be checking if there is a matching account name, but it doesn't seem to fire.

Would anyone know what I've done wrong?

1 Answer 1

1

It looks like you're pushing the exact same blankDataArr each time - you're not pushing a new array, you're pushing the same array to all.

For a more minimal example:

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

For what you're trying to do, it looks like it'd be a lot easier to make an object or Map indexed by AccountName first, that way you just have to access or create the AccountName property while iterating, and assign to the appropriate year.

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);

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks so much! Sorry, I'm not good at ES6 at all. How would I add more (static) data to the new object? Eg: I need to add "type": "bar" to each. I tried a few ways but couldn't figure it out.
Can't say for sure without knowing exactly what sort of data, but perhaps you just need to add a property or few to the object returned in the final .map? ({ name, data }) to ({ name, data, someOtherProp }) or ({ name, data, type: 'bar' })

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.