I have two object arrays of different sizes:
const generalValues= [{time: "08:10", general: 50}, {time: "08:15", general: 60}, {time: "08:20": general: 70},...]
const specValues= [{time: "08:00", spec: 30}, {time: "08:10", spec: 60}, {time: "08:15": spec: 20},...]
I would like to combine them into a list based on time:
const result = [{time: "08:00", general: null, spec: 30},
{time: "08:10", general: 50, spec: 60},
{time: "08:15", general: 60, spec: 20},
{time: "08:20", general: 70, spec: null}...]
I have tried with reduce and map:
const resultMap = generalValues.reduce((item, {time, value}) => (item[time] = value, item), {})
const final = specValues.map(({time, ...rest}) =>
Object.assign({time}, rest, resultMap[time] ? {value: resultMap[time]} : {}))
But its not what I want. Please help me how can I do this?
CodePudding user response:
You can use Array.reduce()
on the concatenated arrays to group the items by date
, then update the general
or spec
property if they do not exist for the given date value.
This creates a map object with an entry like { date, general, spec } for each date.
We can use Object.values()
to get the result as an array.
const generalValues = [{time: '08:10', general: 50}, {time: '08:15', general: 60}, {time: '08:20', general: 70}]
const specValues = [{time: '08:00', spec: 30}, {time: '08:10', spec: 60}, {time: '08:15', spec: 20}]
const resultUnsorted = Object.values([...generalValues, ...specValues].reduce((acc, { time, general = null, spec = null }) => {
acc[time] = acc[time] || { time };
acc[time].general = acc[time].general || general;
acc[time].spec = acc[time].spec || spec;
return acc;
}, {}))
const resultSorted = resultUnsorted.sort(({ time: a},{ time: b}) => a.localeCompare(b));
console.log('Result:', resultSorted);
.as-console-wrapper { max-height: 100% !important; }