console.log
console.log

Reputation: 184

Multiply/Clone multiple times objects inside and array in JavaScript

Having an array of objects in this format:

const data = [
{country_id: 1, country: "Greece", value: 3},
{country_id: 2, country: "Cyprus", value: 2},
{country_id: 3, country: "Turkey", value: 4}
]

how can I multiply/clone each of the objects to get the following array of objects using JavaScript? I want to multiply each object as many times as specified in value and get a new array.

const new_data = [
{id: 1, country_id: 1, country: "Greece", value: 3},
{id: 2, country_id: 1, country: "Greece", value: 3},
{id: 3, country_id: 1, country: "Greece", value: 3},
{id: 4, country_id: 2, country: "Cyprus", value: 2},
{id: 5, country_id: 2, country: "Cyprus", value: 2},
{id: 6, country_id: 3, country: "Turkey", value: 4},
{id: 7, country_id: 3, country: "Turkey", value: 4},
{id: 8, country_id: 3, country: "Turkey", value: 4},
{id: 9, country_id: 3, country: "Turkey", value: 4}
]

My best attempt so far is this one using Object.assign but unfortunately the map returns the same array as in data:

const new_data = data.map((d, i) => {
    for (var i = 0; i < d.mult; ++i) {
      Object.assign({}, d[i]);
    }
    return d;
 })

Upvotes: 0

Views: 1526

Answers (3)

dave
dave

Reputation: 64657

You could do it like this, where you simply fill an array with value elements, and map it to a clone of the original element:

const data = [
{country_id: 1, country: "Greece", value: 3},
{country_id: 2, country: "Cyprus", value: 2},
{country_id: 3, country: "Turkey", value: 4}
]

console.log(
    data.flatMap((el) => new Array(el.value).fill(null).map(e => ({...el}))))

Upvotes: 3

Sajeeb Ahamed
Sajeeb Ahamed

Reputation: 6390

You can do it using Array.from() and reduce. Try this-

Here you can create a temporary array using Array.from({length: X}). Here the {length: X} object says the from method to create an array with the length of X.

After that, the callback function of the Array.from() method returns the current item for every iteration. That's it.

const data = [
  {country_id: 1, country: "Greece", value: 3},
  {country_id: 2, country: "Cyprus", value: 2},
  {country_id: 3, country: "Turkey", value: 4}
];

const res = data.reduce((acc, curr) => {
  const tmp = Array.from({length: curr.value}, () => curr);
  acc.push(...tmp);
  return acc;
}, []);

console.log(JSON.stringify(res));
.as-console-wrapper{min-height: 100%!important; top: 0}

Upvotes: 2

Kelvin Schoofs
Kelvin Schoofs

Reputation: 8718

The easiest would be to just create a new array, loop through the old one and add duplicates (with the new id field) to the result array:

const data = [
    { country_id: 1, country: "Greece", value: 3 },
    { country_id: 2, country: "Cyprus", value: 2 },
    { country_id: 3, country: "Turkey", value: 4 }
]

const result = [];

let id = 0;
for (const row of data) {
    for (let i = 0; i < row.value; i++) {
        const newRow = {
            ...row, // copy old data
            id: ++id, // but set this field and increase `id`
        };
        result.push(newRow);
    }
}

console.log(result);

If you want to use something like .map, you'd need to use .flatMap or .map followed by .flat(). Your (flat)map would return an array with the value new rows. You'd still have to fix the country_id though.

Upvotes: 1

Related Questions