I have an array of objects that looks like this:
const data = [
{
"date": "2020-01-02",
"run": [
{"time": "1", "result": 100},
{"time": "2", "result": 150},
{"time": "3", "result": 92}
]
},
{
"date": "2020-01-15",
"run": [
{"time": "1", "result": 90},
{"time": "2", "result": 86},
{"time": "3", "result": 133}
]
},
{
"date": "2020-02-11",
"run": [
{"time": "1", "result": 45},
{"time": "2", "result": 176},
{"time": "3", "result": 108}
]
},
]
I'd like it to look like this:
[
{
"time": 1,
"2020-01-02": 100,
"2020-01-15": 90,
"2020-02-11": 45
},
{
"time": 2,
"2020-01-02": 150,
"2020-01-15": 86,
"2020-02-11": 176
},
{
"time": 3,
"2020-01-02": 92,
"2020-01-15": 133,
"2020-02-11": 108
},
]
I've tried using reduce like this:
const initVal = {
[data[0].date]: data[0].run[0].result
};
const newArr = data.reduce((prev, curr, currIdx) => {
return {
...prev, ...initVal, [curr.date]: curr.run[currIdx-1].result
}
});
but getting this:
{
"2020-01-02": 100,
"2020-01-15": 90,
"2020-02-11": 176,
date: "2020-01-02"
run:[{…}, {…}, {…}]
}
So not quite there yet. I know I need it to iterate over each of the "run" arrays to get all the correct values for each "time" -- how do I set up what's missing?
CodePudding user response:
You can preprocess your array to make it easier for reduce, for example, convert it to the list of pairs [key, payload]
:
data
.flatMap(d =>
d.run.map(r => [r.time, {[d.date]: r.result}]))
This produces:
[
[ '1', { '2020-01-02': 100 } ],
[ '2', { '2020-01-02': 150 } ],
[ '3', { '2020-01-02': 92 } ],
[ '1', { '2020-01-15': 90 } ], etc
Now we can group things together:
.reduce((m, [key, payload]) =>
m.set(key, Object.assign({}, m.get(key), payload)),
new Map)
which creates the following Map
:
Map(3) {
'1' => { '2020-01-02': 100, '2020-01-15': 90, '2020-02-11': 45 },
'2' => { '2020-01-02': 150, '2020-01-15': 86, '2020-02-11': 176 },
'3' => { '2020-01-02': 92, '2020-01-15': 133, '2020-02-11': 108 }
}
The rest should be easy, good luck!
CodePudding user response:
You could use an object for grouping and get the values as result.
const
data = [{ date: "2020-01-02", run: [{ time: "1", result: 100 }, { time: "2", result: 150 }, { time: "3", result: 92 }] }, { date: "2020-01-15", run: [{ time: "1", result: 90 }, { time: "2", result: 86 }, { time: "3", result: 133 }] }, { date: "2020-02-11", run: [{ time: "1", result: 45 }, { time: "2", result: 176 }, { time: "3", result: 108 }] }],
result = Object.values(data.reduce((r, { date, run }) => {
run.forEach(({ time, result }) => {
r[time] ??= { time };
r[time][date] = result;
});
return r;
}, {}));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }