1

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 }
*/
3
  • 1
    arr2.push(arr1[i]) Both the object from the first and the second have the same reference Commented Dec 20, 2019 at 11:30
  • This happens because the array elements are not primitives, hence they are kind of passed by "reference" (though it's not exactly a reference). You need to deep copy the values first, otherwise altering either of them will effectively update both. Commented Dec 20, 2019 at 11:30
  • Related: stackoverflow.com/questions/122102/… Commented Dec 20, 2019 at 11:36

3 Answers 3

3

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

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

Comments

3

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

Comments

2

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

Comments

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.