I have an array of objects that look like this:
[
{
makeYear: 2019,
company: 'Mazda',
fleet: '900'
},
{
makeYear: 2019,
company: 'Mercedes',
fleet: '500'
},
{
makeYear: 2020,
company: 'Honda',
fleet: '390'
},
.....
]
I am trying to merge all the properties for a specific makeYear into one object that should look like this
[
{
makeYear: 2019,
Mazda: 900,
Mercedes: 500,
//other companies present for the year
},
{
makeYear: 2020,
Honda: 390,
//other companies present for the year
},
];
I have tried it doing this way, but no luck.
const mergeObjs = input.reduce((res, item) => {
if (!item.makeYear) return res;
res[item.makeYear] = item;
return res;
}, {});
const merged = input.filter(item => item.makeYear).map(item => {
return {...item, ...(mergeObjs[item.makeYear] || {})}
});
Any idea how I can achieve this? TIA
CodePudding user response:
You can use reduce
to group with makeYear
as a key.
const data = [
{
makeYear: 2019,
company: 'Mazda',
fleet: '900'
},
{
makeYear: 2019,
company: 'Mercedes',
fleet: '500'
},
{
makeYear: 2020,
company: 'Honda',
fleet: '390'
},
]
const result = data.reduce((acc, {makeYear, company, fleet}) => {
let item = acc.find(i => i.makeYear === makeYear);
if (item) {
item[company] = fleet;
} else {
acc.push({
makeYear,
[company]: fleet,
})
}
return acc
}, [])
console.log(result)
CodePudding user response:
You can use reduce()
to collect values for each year. Then use entries()
and map()
to get your desired structure.
This implementation uses a Map
, but you can also use a plain JavaScript object.
const input = [
{
makeYear: 2019,
company: "Mazda",
fleet: "900",
},
{
makeYear: 2019,
company: "Mercedes",
fleet: "500",
},
{
makeYear: 2020,
company: "Honda",
fleet: "390",
},
];
const carsByYearAndMake = input.reduce((carsByYear, carsByMake) => {
if (carsByYear.has(carsByMake.makeYear)) {
const carsForYear = carsByYear.get(carsByMake.makeYear);
carsForYear[carsByMake.company] = carsByMake.fleet;
} else {
carsByYear.set(carsByMake.makeYear, {
[carsByMake.company]: carsByMake.fleet,
});
}
return carsByYear;
}, new Map());
const output = [...carsByYearAndMake.entries()].map(
([year, fleetCountByMake]) => ({ year: year, ...fleetCountByMake })
);
console.log(JSON.stringify(output, null, 4));
/* StackOverflow snippet: console should overlap rendered HTML area */
.as-console-wrapper { max-height: 100% !important; top: 0; }