Reputation: 149
I never seem to understand JavaScript fully. Please explain this to me.
I have an array of objects called arr1. In this simplified example, it has only two members; name and someValue. The array is sorted by name and the content looks like this:
Harry 1
Joe 2
Joe 3
Peter 4
I want to create another array called arr2. It should hold the unique names from arr1. If a duplicate is found, the someValue is added for that name. I basically want this as content in arr2:
Harry 1
Joe 5 <-- the two values from Joe in arr1 sums up to 5
Peter 4
So I came up with the script below. The resulting arr2 is exactly what I want. However, the arr1 is also updated and that's not what I desire.
Why is this happening and how can I fix it?
var arr1 = [];
var arr2 = [];
arr1.push({name: 'Harry', someValue: 1});
arr1.push({name: 'Joe', someValue: 2});
arr1.push({name: 'Joe', someValue: 3});
arr1.push({name: 'Peter', someValue: 4});
let previousName = '';
for (var i=0;i<arr1.length;i++) {
if (arr1[i].name == previousName) {
arr2[arr2.length-1].someValue += arr1[i].someValue;
} else {
arr2.push(arr1[i]);
previousName = arr1[i].name;
}
}
/* Result arr1 is not ok:
0: Object { name: "Harry", someValue: 1 }
1: Object { name: "Joe", someValue: 5 } <-- I want the value 2 to be preserved
2: Object { name: "Joe", someValue: 3 }
3: Object { name: "Peter", someValue: 4 }
Result arr2 is ok:
0: Object { name: "Harry", someValue: 1 }
1: Object { name: "Joe", someValue: 5 }
2: Object { name: "Peter", someValue: 4 }
*/
Upvotes: 1
Views: 1324
Reputation: 33
Thing is when you modify those values, as they are references, mean that they are connected, they are pointing to the same memory location where it keeps the value. Creating a duplicate, but separate array a2
such that changing a1[k]
will not cause a2[k]
to match the modified a1[k]
requires cloning.
Shallow copies can be done using a simple loop or slicing. JSON.parse
and JSON.stringify
creates deep copies.
This link will explain you deeper why and how to solve it. How to clone an array in JavaScript
Upvotes: 2
Reputation: 38164
It happens because arrays and objects are reference types. So when you are editing a reference , then it means that all objects will be edited.
So try to use spread operator to create brand new object:
arr2.push({...arr1[i]});
or Object.assign
:
arr2.push(Object.assign({}, arr1[i]));
Upvotes: 3
Reputation: 16433
This is because you are pushing the object instance from arr1
onto arr2
, instead of a copy.
Instead, simply create a new instance of the object when pushing onto arr2
and you will correct the problem.
Replace this line (which pushes the instance from arr1
onto arr2
:
arr2.push(arr1[i]);
With this line (which creates a new instance and pushes it onto arr2
:
arr2.push({name: arr1[i].name, someValue: arr1[i].someValue});
Here's a working snippet showing this:
var arr1 = [];
var arr2 = [];
arr1.push({name: 'Harry', someValue: 1});
arr1.push({name: 'Joe', someValue: 2});
arr1.push({name: 'Joe', someValue: 3});
arr1.push({name: 'Peter', someValue: 4});
;
let previousName = '';
for (var i = 0; i < arr1.length; i++) {
if (arr1[i].name == previousName) {
arr2[arr2.length - 1].someValue += arr1[i].someValue;
} else {
arr2.push({name: arr1[i].name, someValue: arr1[i].someValue});
previousName = arr1[i].name;
}
}
console.log(arr1);
console.log(arr2);
Upvotes: 3