Reputation: 220
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"?!
Upvotes: 1
Views: 92
Reputation: 8284
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()}
Upvotes: 4
Reputation: 73241
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);
Upvotes: 1