I have data like this :
const cards = [
{ name: "angular2" },
{ name: "vue" },
{ name: "react" },
{ name: "grunt" },
{ name: "phantomjs" }
];
I want to duplicate and shuffle this array. Also i want to add id property to each item.
const duplicateCards = (arr) => {
const duplicatedArr = [...arr, ...arr];
for (let i = duplicatedArr.length - 1; i >= 0; i--) {
duplicatedArr[i].id = i;
randomIndex = Math.floor(Math.random() * i + 1);
console.log(duplicatedArr[i]);
[duplicatedArr[i], duplicatedArr[randomIndex]] = [duplicatedArr[randomIndex], duplicatedArr[i]];
}
return duplicatedArr;
};
The duplicateCards(cards) function returns an output like this:
[
{ name: 'vue', id: 1 },
{ name: 'angular2', id: 0 },
{ name: 'vue', id: 1 },
{ name: 'grunt', id: 7 },
{ name: 'phantomjs', id: 4 },
{ name: 'phantomjs', id: 4 },
{ name: 'grunt', id: 7 },
{ name: 'react' },
{ name: 'react' },
{ name: 'angular2', id: 0 }
]
I tried concat() method but I got same result. I want to add a unique id. What is my mistake ? How can I solve this?
This happens because although you spread the array with [...arr, ...arr], creating a new array, the object references are still the same, so every object is now referenced twice. This means that any mutation you do (like with assigning to the id property) will be visible at two places in the array.
Secondly, you should assign the id property before the phase where you start swapping, as you may meet the same object a second time and then assign a different id to it, while other objects, which get swapped to the index i, will not get an id assigned.
Here is how it could work, by chaining a .map on the created array which creates new objects:
const duplicateCards = (arr) => {
const duplicatedArr = [...arr, ...arr].map((o, id) => ({...o, id }));
for (let i = duplicatedArr.length - 1; i >= 0; i--) {
let randomIndex = Math.floor(Math.random() * i + 1);
[duplicatedArr[i], duplicatedArr[randomIndex]] = [duplicatedArr[randomIndex], duplicatedArr[i]];
}
return duplicatedArr;
};
const cards = [
{ name: "angular2" },
{ name: "vue" },
{ name: "react" },
{ name: "grunt" },
{ name: "phantomjs" }
];
console.log(duplicateCards(cards));