I cannot seem to get my head wrapped around the JS array.reduce() function. I have the following input array and want to transform it into an object with reduce to get the following output:
Input:
let cars = [
{ name: 'bmw', type: 'diesel' },
{ name: 'mercedes', type: 'gas' },
{ name: 'honda', type: 'electric' },
{ name: 'bmw', type: 'gas' }
];
Desired output:
{
"bmw": [{type: 'diesel'}, {type: 'gas'}],
"mercedes": [{"type": "gas"}],
"honda": [{"type": "electric"}]
}
What I have tried:
let output = input.reduce((acc, item) => {
if (!acc[item.name]) {
acc[item.name] = [{ type: item.type }];
} else {
acc[item.name] = []; // How can I add the value of the second bmw occurrence into the array?
}
return acc;
}, {});
console.log(output);
What I have got:
{
"bmw": [],
"mercedes": [{"type": "gas"}],
"honda": [{"type": "electric"}]
}
Any pointers greatly appreciated as JS newbie here. Thanks!
CodePudding user response:
You can spread existing array value and add new value
let output = cars.reduce((acc, item) => {
if (!acc[item.name]) {
acc[item.name] = [{ type: item.type }];
} else {
acc[item.name] = [...acc[item.name], { type: item.type }]; // spread and insert
}
return acc;
}, {});
Reference https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax
CodePudding user response:
This is basically the same logic as kwaiks solution. Main differences is this does not infer truthiness from whether an entry is defined but askes explicitly about the property and instead of spread this simply uses the push method.
let output = cars.reduce((acc, currentValue, currentIndex, arr) => {
acc.hasOwnProperty(currentValue.name)
? acc[currentValue.name].push({type: currentValue.type})
: acc[currentValue.name] = [{type: currentValue.type}];
return acc;
}, {});
If you do not mean to redeclare output you may want to swap let
with const
.