Home > Net >  Reduce method on array of objects with conditional
Reduce method on array of objects with conditional

Time:10-13

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)

  • Related