1

Hi I'm playing around with node.js and Javascript for an upcoming project. I have an array of template objects called templateValues.

Now I'd like to copy these two objects with altered id's into an new array myArray.

let templateValues = [{'id':1 , 'type': 'a'},{'id':2 , 'type': 'b'}];
let myArray = [];

for (let index = 0; index < 10; index++) {
 myArray =  myArray.concat(templateValues.map(e => {
   e.id = Math.random(); // suppose this gives a unique id
   return e;
  }).slice(0));	
}
console.log(myArray);

OUTPUT:

{id: 0.13413583461207668, type: "a"}
{id: 0.7426427992455211, type: "b"}
{id: 0.13413583461207668, type: "a"}
{id: 0.7426427992455211, type: "b"}
{id: 0.13413583461207668, type: "a"}
{id: 0.7426427992455211, type: "b"}
{id: 0.13413583461207668, type: "a"}
{id: 0.7426427992455211, type: "b"}
...

Why are the ids all the same even if I do slice(0) of the altered templateValues-array to get a "data-copy"?!

2
  • 2
    You're modifying the original object references, not adding new objects to the list. The IDs will all be the same. Commented Jun 28, 2018 at 20:01
  • slice() makes a shallow copy, not a deep copy. Commented Jun 28, 2018 at 20:32

2 Answers 2

4

When you call slice, you are modifying the array object, not the contents of the array itself. There are no lines of code in your example that clone the underlying object, and thus, when you set e.id = Math.random(), you are editing the same object over and over again.

The fix here is to clone e before you modify it. Try Object.assign({}, e) before editing it to make a shallow copy of each item.

See the below example:

let templateValues = [{'id':1 , 'type': 'a'},{'id':2 , 'type': 'b'}];
let myArray = [];

for (let index = 0; index < 10; index++) {
    myArray =  myArray.concat(templateValues.map(e => {
       const eCopy = Object.assign({}, e, {id: Math.random()})
       return eCopy;
  }).slice(0)); 
}
console.log(myArray);

You can also use the ES2018 object spread syntax to achieve the same result. Simply replace Object.assign with {...e, id: Math.random()}

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

Comments

1

The other answer and comment already explains the problem, so I'll just offer a solution - you can use below to get what you need, the length of the new array can be set to whatever you want, the types will repeat itself in the same order of your original array

let templateValues = [{'id':1 , 'type': 'a'},{'id':2 , 'type': 'b'}];
const newArr = Array.from ({length: 10}, (_, i) => ({
    id: Math.random(),
    type: templateValues[i % templateValues.length].type
}));
console.log(newArr);

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.