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?
-
Your question is a bit vague but, if I understand it correctly, you want to have a new row with the second values of the second row?Giesburts– Giesburts2020年02月05日 12:09:14 +00:00Commented Feb 5, 2020 at 12:09
6 Answers 6
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; }
1 Comment
o, r, k and j ;)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)
Comments
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);
Comments
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)
}, []);
Comments
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);
Comments
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; }