I have an array of objects:
const fruits = [{
type: oranges,
amount: 10
},
{
type: apples,
amount: 0,
}, {
type: oranges,
amount: 5
}
]
I need to do the following:
- sum up the fruits, if they're the same (f.ex. sum up oranges: {type: oranges, amount: 15})
- add a new key-value pair to object, depending on how many times it is present in the array (f.ex. oranges are present two times: {types: oranges, amount: 15, count: 2} and apples are present one time {types: apples, amount: 0, count: 1} )
So my goal is to have something like this:
const fruits = [{
type: oranges,
amount: 15,
count: 2
},
{
type: apples,
amount: 0,
count: 1
}
]
I found out that the reduce method is a good way to achieve this. I'm working with the following code (this should sum up the amount), but no matter what I try I don't get the result. I just get a new key-value {..., marks: NaN} - so maybe there's a better approach:
const fruits = [{
type: "oranges",
amount: 10
},
{
type: "apples",
amount: 0,
}, {
type: "oranges",
amount: 5
}
]
const endresult = Object.values(fruits.reduce((value, object) => {
if (value[object.type]) {
['marks'].forEach(key => value[object.type][key] = value[object.type][key] object[key]);
} else {
value[object.type] = { ...object
};
}
return value;
}, {}));
console.log(endresult)
I'm not sure what I'm doing wrong and how can I add the new key-value pair to count the times the object is present in the array? Could someone point me in the right direction? Thanks!
CodePudding user response:
Your code looks more complex than what is required. Somewhere you must be adding an undefined
to a number and hence getting NaN
(not a number).
Also :
- you are not initializing the
count
property. - you are not adding the
amount
andcount
, in the if condition.
Making a few changes to your code itself this can be fixed:
const fruits = [{
type: "oranges",
amount: 10
},
{
type: "apples",
amount: 0,
}, {
type: "oranges",
amount: 5
}
]
const endresult = Object.values(fruits.reduce((value, object) => {
if (value[object.type]) {
value[object.type].amount = object.amount;
value[object.type].count ;
} else {
value[object.type] = { ...object , count : 1
};
}
return value;
}, {}));
console.log(endresult)
CodePudding user response:
You can easily achieve the result using Map, reduce, and Array.from
const fruits = [
{
type: "oranges",
amount: 10,
},
{
type: "apples",
amount: 0,
},
{
type: "oranges",
amount: 5,
},
];
const endresult = Array.from(
fruits
.reduce((map, curr) => {
if (!map.has(curr.type)) map.set(curr.type, { ...curr, count: 1 });
else {
map.get(curr.type).amount = curr.amount;
map.get(curr.type).count ;
}
return map;
}, new Map())
.values()
);
console.log(endresult);
/* This is not a part of answer. It is just to give the output fill height. So IGNORE IT */
.as-console-wrapper { max-height: 100% !important; top: 0; }
CodePudding user response:
This reduce works better
const fruits = [{ type: "oranges", amount: 10 }, { type: "apples", amount: 0}, { type: "oranges", amount: 5 }]
const endresult = fruits.reduce((acc,fruit) => {
acc[fruit.type] = acc[fruit.type] || fruit;
const theFruit = acc[fruit.type]
theFruit.count = !!theFruit.count ? theFruit.count : 0;
theFruit.count
theFruit.amount = fruit.amount
return acc;
}, {});
console.log(Object.values(endresult))