Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Copying an array of objects into another array in javascript [duplicate]

How can I copy every element of an array (where the elements are objects), into another array, so that they are totally independent? I don't want changing an element in one array to affect the other.

like image 977
hAlE Avatar asked Apr 26 '13 09:04

hAlE


People also ask

How do you duplicate an array in JavaScript?

Because arrays in JS are reference values, so when you try to copy it using the = it will only copy the reference to the original array and not the value of the array. To create a real copy of an array, you need to copy over the value of the array under a new value variable.

How do you clone an array of objects?

it("creates separate objects in array", () => { const clone = deepClone(people); clone[0]. name = "Jack"; expect(clone[0]. name). toBe("Jack"); expect(people[0].

Can you copy an array to another array?

Answer: There are different methods to copy an array. You can use a for loop and copy elements of one to another one by one. Use the clone method to clone an array. Use arraycopy() method of System class.

Why does changing an array in JavaScript affect copies of the array?

An array in JavaScript is also an object and variables only hold a reference to an object, not the object itself. Thus both variables have a reference to the same object.


2 Answers

The key things here are

  1. The entries in the array are objects, and
  2. You don't want modifications to an object in one array to show up in the other array.

That means we need to not just copy the objects to a new array (or a target array), but also create copies of the objects.

If the destination array doesn't exist yet...

...use map to create a new array, and copy the objects as you go:

const newArray = sourceArray.map(obj => /*...create and return copy of `obj`...*/); 

...where the copy operation is whatever way you prefer to copy objects, which varies tremendously project to project based on use case. That topic is covered in depth in the answers to this question. But for instance, if you only want to copy the objects but not any objects their properties refer to, you could use spread notation (ES2015+):

const newArray = sourceArray.map(obj => ({...obj})); 

That does a shallow copy of each object (and of the array). Again, for deep copies, see the answers to the question linked above.

Here's an example using a naive form of deep copy that doesn't try to handle edge cases, see that linked question for edge cases:

function naiveDeepCopy(obj) {     const newObj = {};     for (const key of Object.getOwnPropertyNames(obj)) {         const value = obj[key];         if (value && typeof value === "object") {             newObj[key] = {...value};         } else {             newObj[key] = value;         }     }     return newObj; } const sourceArray = [     {         name: "joe",         address: {             line1: "1 Manor Road",             line2: "Somewhere",             city: "St Louis",             state: "Missouri",             country: "USA",         },     },     {         name: "mohammed",         address: {             line1: "1 Kings Road",             city: "London",             country: "UK",         },     },     {         name: "shu-yo",     }, ]; const newArray = sourceArray.map(naiveDeepCopy); // Modify the first one and its sub-object newArray[0].name = newArray[0].name.toLocaleUpperCase(); newArray[0].address.country = "United States of America"; console.log("Original:", sourceArray); console.log("Copy:", newArray);
.as-console-wrapper {     max-height: 100% !important; }

If the destination array exists...

...and you want to append the contents of the source array to it, you can use push and a loop:

for (const obj of sourceArray) {     destinationArray.push(copy(obj)); } 

Sometimes people really want a "one liner," even if there's no particular reason for it. If you refer that, you could create a new array and then use spread notation to expand it into a single push call:

destinationArray.push(...sourceArray.map(obj => copy(obj))); 
like image 196
T.J. Crowder Avatar answered Oct 05 '22 23:10

T.J. Crowder


Easy way to get this working is using:

var cloneArray = JSON.parse(JSON.stringify(originalArray)); 

I have issues with getting arr.concat() or arr.splice(0) to give a deep copy. Above snippet works perfectly.

like image 36
jsbisht Avatar answered Oct 06 '22 01:10

jsbisht