0

I have a question related to finding count of objects inside an array. My array is this:

completePositions: any = [
    {
      totalPositions: [
        { position: "CNA", count: 2 },
        { position: "LVN", count: 5 },
        { position: "RNA", count: 8 }
      ]
    },
    {
      totalPositions: [
        { position: "CNA", count: 13 },
        { position: "LVN", count: 11 },
        { position: "RNA", count: 15 }
      ]
    }
  ];

I was trying to find the total count of each position in totalPositions array, so that my final array will look like this:

totalPositionsCount = [
        { position: "CNA", count: 15 },
        { position: "LVN", count: 16 },
        { position: "RNA", count: 23 }
  ];

I created a function to sum up each position in 'totalPositons' array and push the sum to totalPositionsCount. My function does the job and I got the total count, but it changes the parent array 'completePositions' and first 'totalPositions' of 'completePositions' gets replaced by the 'totalPositionsCount' array. I tried to create a backup of 'completePositions' and use it for calculations, still both the arrays first 'totalPositions' gets replaced by 'totalPositionsCount' array.

My function to sum up the position is:

codeToShowTotalResources() {
    for (let totPos of this.completePositions) {
        for (let eachPos of totPos.totalPositions) {
            console.log("eachPos", eachPos);

            let postCountIndex = this.totalPositionsCount.findIndex(
                pos => pos.position == eachPos.position
            );

            if (postCountIndex != -1) {
                console.log("Already exists, sum up positions");
                let positionCount = this.totalPositionsCount[postCountIndex].count + eachPos.count;
                this.totalPositionsCount[postCountIndex].count = positionCount;
            } else {
                console.log("Add it for first time");
                this.totalPositionsCount.push(eachPos);
            }
        }

    }
}

If I replace this.totalPositionsCount[postCountIndex].count = positionCount; with this.totalPositionsCount[postCountIndex] = { position: eachPos.position, count: positionCount }; then it works just fine. I want to know what I was doing wrong, or is it supposed to work this way.

I've opened a sample project in stackblitz any help will be great :)

Gaius Mathew
  • 187
  • 1
  • 8

1 Answers1

2

When you do this: this.totalPositionsCount.push(eachPos), the eachPos variable represents the entry from completePositions. So now this.totalPositionsCount and this.completePositions have a reference to the same object. If you modify that object the change shows up in both places, because it's the same object.

Here's an alternative approach using reduce and forEach:

const completePositions = [
  {
    totalPositions: [
      {position: "CNA", count: 2},
      {position: "LVN", count: 5},
      {position: "RNA", count: 8}
    ]
  },
  {
    totalPositions: [
      {position: "CNA", count: 13},
      {position: "LVN", count: 11},
      {position: "RNA", count: 15}
    ]
  }
];

const totals = completePositions
  .map(x => x.totalPositions)
  .reduce((acc, totalPositions) => {
    totalPositions.forEach(({position, count}) => {
      acc[position] = (acc[position] || 0) + count;
    })
    return acc;
  }, {})
  
console.log(totals);
ray
  • 26,557
  • 5
  • 28
  • 27
  • So when i write let copyOfArray = parentArray, it is not creating a copy of parentArray, but rather a reference to parentArray, and each calculation I've doing to the copy array gets reflected in parent array also. Thank you for your answer and clean alternative approach. – Gaius Mathew Jun 18 '20 at 18:21
  • Correct. In that case copyOfArray and parentArray point to the same array and changes will be reflected in both places. – ray Jun 18 '20 at 18:26
  • The simplest way is via the [spread operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax): `const newArray = [...oldArray]`. Note, however, that if the array contains references to other objects those will still be linked. In other words, you'll have two arrays that can be modified independently, but their contents may still contain references to common/shared objects. If you need to create a wholly independent copy of nested arrays and objects, there are [ways to do that](https://stackoverflow.com/a/38417085/636077). – ray Jun 18 '20 at 18:34
  • Thanks for your help :) – Gaius Mathew Jun 18 '20 at 18:39