Home > Enterprise >  javascript duplicate array and change values
javascript duplicate array and change values

Time:09-25

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 dublicatedArr = [...arr, ...arr];
  for (let i = dublicatedArr.length - 1; i >= 0; i--) {
    dublicatedArr[i].id = i;
    console.log(dublicatedArr[i]);
    [dublicatedArr[i], dublicatedArr[randomIndex]] = [dublicatedArr[randomIndex],dublicatedArr[i]];
  }
  return dublicatedArr;
};

duplicateCards(cards) This function gives 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 wanted to add a unique id. What is my mistake ? How can i solve this?

CodePudding user response:

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 dublicatedArr = [...arr, ...arr].map((o, id) => ({...o, id }));
  for (let i = dublicatedArr.length - 1; i >= 0; i--) {
    let randomIndex = Math.floor(Math.random() * i);
    [dublicatedArr[i], dublicatedArr[randomIndex]] = [dublicatedArr[randomIndex],dublicatedArr[i]];
  }
  return dublicatedArr;
};

const cards = [
  { name: "angular2" },
  { name: "vue" },
  { name: "react" },
  { name: "grunt" },
  { name: "phantomjs" }
];

console.log(duplicateCards(cards));

CodePudding user response:

You can use the Fisher-Yates algorithm to shuffle the elements after duplicating them using Array#flatMap:

const _shuffleArr = arr => {
  for (let i = arr.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i   1));
    const temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
  }
  return arr;
}

const duplicateCards = (arr = []) => 
  _shuffleArr(
    arr.flatMap((card, id) => [ { ...card, id }, { ...card, id } ])
  );

console.log( duplicateCards([ { name: "angular2" }, { name: "vue" }, { name: "react" }, { name: "grunt" }, { name: "phantomjs" } ]) );

  • Related