I have an array of objects data
that i'm attempting to get the total of both shoe sizes in a object:
const data = [
{ "shoeSize": "size 10", "total": 9,},
{ "shoeSize": "size 10", "total": 3 },
{ "shoeSize": "size 5", "total": 2}
]
I am having issues with counting size 10
apart from size 5
. I've attempted to use the reduce method but add a conditional to only add the total count if the names match
For example:
const data = [
{ shoeSize: "size 10", total: 9},
{ shoeSize: "size 10", total: 3},
{ shoeSize: "size 5", total: 2}
]
const grandTotal = data.reduce((prev, curr) => {
return {
shoeSize10Total: prev.shoeSize === "size 10" || curr.shoeSize === "size 10" && prev.total curr.total,
shoeSize5Total: prev.shoeSize === "size 5" || curr.shoeSize === "size 5" && prev.total curr.total
}
});
console.log(grandTotal)
This method is returning NaN
and false
instead of returning the total amount of numbers for each.
I've tried looking up a solution and found something similar with this post here but they are filtering to return the value of 1. I would like to return both in an object
I'm expecting an object that looks like :
const grandTotal = {
shoeSize10Total: 12
shoeSize5Total: 2
}
CodePudding user response:
I think using .reduce
here makes things too convoluted. Consider a plain loop where you increment the appropriate property an an object declared outside.
const data = [
{ shoeSize: "size 10", total: 9},
{ shoeSize: "size 10", total: 3},
{ shoeSize: "size 5", total: 2}
];
const grandTotal = {};
for (const { shoeSize, total } of data) {
const digits = shoeSize.match(/\d /)[0];
if (!digits) continue;
const key = `shoeSize${digits}Total`;
grandTotal[key] = (grandTotal[key] || 0) total;
}
console.log(grandTotal);
CodePudding user response:
We could implement basic approaches using EcmaScript Methods such as filter. Take a look at this code snippet, pal. I certainly hope this helps, buddy!
const data = [
{ shoeSize: "size 10", total: 9 },
{ shoeSize: "size 10", total: 3 },
{ shoeSize: "size 5", total: 2 },
];
let shoeSize10Total = 0;
let shoeSize05Total = 0;
const grandTotal = (data) => {
data.filter((el) => {
if (el.shoeSize === "size 10") {
shoeSize10Total = el.total;
} else {
shoeSize05Total = el.total;
}
});
return { shoeSize10Total, shoeSize05Total };
};
console.log(grandTotal(data));
CodePudding user response:
One of issues is that you are not using the initialValue
of reduce method.
Moreover, the approach to build the grandTotal
is far from the best as the values are hardcoded into the reduce
handler, for multiple size
values that code will be a mess.
A cleaner approach is to create a mapping of input values to output keys, then in the reduce
handler just to use that mapping for lookups, like this:
const data = [
{ shoeSize: "size 10", total: 9},
{ shoeSize: "size 10", total: 3},
{ shoeSize: "size 5", total: 2}
];
const map = {
'size 5': 'shoeSize5Total',
'size 10': 'shoeSize10Total'
};
const grandTotal = data.reduce((o, {shoeSize: s, total}) =>
(o[map[s]] = (o[map[s]] ?? 0) total, o), {});
console.log(grandTotal);
CodePudding user response:
little info about below code
firstly use {}
object as initial value to reduce function
now extract shoeSize from data array and use it as a key for new object
now write a condition if that key exist in new object then increment the value otherwise create a new property to object
boom at the end you will have a sorted object as a result
const data = [
{ shoeSize: "size 10", total: 9 },
{ shoeSize: "size 10", total: 3 },
{ shoeSize: "size 5", total: 2 }
]
let res = data.reduce((main,each)=>{
let num = each.shoeSize.match(/\d /)[0],
newKey = `shoeSize${num}Total`,
exist = typeof main[newKey] !== "undefined"
if(exist){main[newKey] = each.total}
else{main[newKey] = each.total}
return main
},{})
console.log(res)