Denis
Denis

Reputation: 296

Create new array based an array

I have an array as follows:

const data = [
 { new_id: "56", old_id: "229", ratio: "0.1", week: "20" },
 { new_id: "55", old_id: "56,96", ratio: "0.2,0.4", week: "20" }
];

I expect the new array to look like this:

const expectedData = [
 { new_id: "56", old_id: "229", ratio: "0.1", week: "20" },
 { new_id: "55", old_id: "56", ratio: "0.2", week: "20" },
 { new_id: "55", old_id: "96", ratio: "0.4", week: "20" }
];

I writed some code, but now i'm stuck

const result = data.map(data => {
  return {
   ...data,
   old_id: data.old_id.split(","),
   ratio: data.ratio.split(",")
  };
});

How to solve this?

Upvotes: 3

Views: 108

Answers (6)

Yosvel Quintero
Yosvel Quintero

Reputation: 19070

You can use Array.prototype.reduce()

const data = [{ new_id: "56", old_id: "229", ratio: "0.1", week: "20" }, { new_id: "55", old_id: "56,96", ratio: "0.2,0.4", week: "20" }]

const result = data.reduce((a, { new_id, old_id, ratio, week }) =>
  [...old_id.split(',').map((id, i) => ({ new_id, old_id: id, ratio: ratio.split(',')[i], week })), ...a], [])

console.log(result)
.as-console-wrapper { max-height: 100% !important; top: 0; }

Upvotes: 0

Siva Kondapi Venkata
Siva Kondapi Venkata

Reputation: 11001

Another version with reduce, split and using comma operator.

const data = [
  { new_id: "56", old_id: "229", ratio: "0.1", week: "20" },
  { new_id: "55", old_id: "56,96", ratio: "0.2,0.4", week: "20" }
];

const updated = data.reduce(
  (acc, curr) => (
    (ratios = curr.ratio.split(",")),
    curr.old_id
      .split(",")
      .forEach((old_id, i) => acc.push({ ...curr, old_id, ratio: ratios[i] })),
    acc
  ),
  []
);

console.log(updated);

Upvotes: 0

Nina Scholz
Nina Scholz

Reputation: 386560

You could take a Array#flatMap approach and map old_id/ratio as well.

const
    data = [{ new_id: "56", old_id: "229", ratio: "0.1", week: "20" }, { new_id: "55", old_id: "56,96", ratio: "0.2,0.4", week: "20" }],
    keys = ['old_id', 'ratio'],
    result = data.flatMap(o => keys.reduce((r, k, j) => {					
        o[k].split(',').forEach((v, i) => {
            r[i] = r[i] || { ...o };
            r[i][keys[j]] = v;
        });
        return r;
    }, []));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Upvotes: 4

pbialy
pbialy

Reputation: 1083

In case when from an array you want to get another array with different number of elements - always think about reduce.

Here's my code for the solution:

data.reduce((prev, curr) => {
  const splittedRatio = curr.ratio.split(',');
  const splittedOldId = curr.old_id.split(',');
  const newData = [];

  splittedRatio.forEach((rat, i) => {
    newData.push({
      ...curr,
      ratio: rat,
      old_id: splittedOldId[i]
    });
  });
  return prev.concat(newData)
}, []);

Upvotes: 0

StepUp
StepUp

Reputation: 38094

You can use reduce method to check whether old_id contains , and then just push desired items:

const result = data.reduce((a,c)=>{
     let splittedOld_id = c.old_id.split(',');
     splittedOld_id.forEach((el, i)=>{
         a.push({new_id: c.new_id, old_id: el, ratio: c.ratio.split(',')[i], week: c.week});
     });
     return a;
 }, []);

An example:

const data = [
  { new_id: "56", old_id: "229", ratio: "0.1", week: "20" },
  { new_id: "55", old_id: "56,96", ratio: "0.2,0.4", week: "20" }
 ];

 const result = data.reduce((a,c)=>{
     let splittedOld_id = c.old_id.split(',');
     splittedOld_id.forEach((el, i)=>{
         a.push({new_id: c.new_id, old_id: el, ratio: c.ratio.split(',')[i], week: c.week});
     });
     return a;
 }, []);

 console.log(result);

Upvotes: 1

Harun Yilmaz
Harun Yilmaz

Reputation: 8558

You can use Array.reduce() to iterate over and use a for...of loop inside the iteration as followings:

const data = [{
    new_id: "56",
    old_id: "229",
    ratio: "0.1",
    week: "20"
  },
  {
    new_id: "55",
    old_id: "56,96",
    ratio: "0.2,0.4",
    week: "20"
  }
];

const newData = data.reduce((acc, cur) => {
  let old_ids = cur.old_id.split(',')
  let ratios = cur.ratio.split(',')
  for(let [i, old_id] of old_ids.entries()){
    acc.push(
    {
      ...cur,
      old_id,
      ratio: ratios[i]
    }
    )
  }
  return acc;
}, [])

console.log(newData)

Upvotes: 2

Related Questions