Home > OS >  Get the sum per date of nested objects in an array
Get the sum per date of nested objects in an array

Time:10-09

I have an array with nested objects that looks like the one below. What I'd like to do is loop through it calculate the sum of each item per date.

For example pc screen = ?

I cannot seem to figure out how to do it properly. I have found this solution, it works great in console.log() but I cannot figure out how to output the result in a div. Should I use a map function ?


  const amountPerDate = data.forEach(function (i) {
    const sum = i.item.reduce(function (sum, elem) {
      return sum   elem.price;
    }, 0);
    console.log("the total sum is "   sum);
  });

The array:

Array

CodePudding user response:

The code you have posted doesn't seem quite right since forEach won't return anything, and the inner variable sum is not actually available for React to render since it is not in scope (in JavaScript, variables can not escape their containing function, which is function (i) { -- nothing outside of that function can see it).

You were roughly on the right tracks with needing map since that will return an array that represents an accumulation of the return values in the nested callback.

 const amountsPerDate = data.map((i) => {
    return i.item.reduce(function (sum, elem) {
      return sum   elem.price;
    }, 0);
  });

amountsPerDate will now be an array of the sums. However, in this process, youve lost the info about which sum correlates to which date. So we need more. We can modify to return both the sum alongside the date (an array of objects, each with a sum and date inside).

 const amountsPerDate = data.map((i) => {
    return {
       sum: i.item.reduce(function (sum, elem) {
           return sum   elem.price;
       }, 0),
       date: i.date
  });

Now, you should have something in amountsPerDate that looks like this:

[
    { date: '01/01/2022', sum: 200 },
    { date: '02/01/2022', sum: 30},
]

To display in your react component, it's just a case of rendering it, which will require you to map over this new data and return an element for each entry. You haven't posted your full component, but it will be something like this in your JSX:

<div>
    {amountsPerDate.map(sum => 
         <div>Date: {sum.date}. Total: {sum.sum}</div>
    )}
</div>

Of course you can play with this and move it around as you see fit so it fits however you want it laid out.

It's really worth your time understanding map and the differences with foreach since it's so ubiquitous in functional programming. Foreach and map both loop over each item. But map allows you to return a value within the loop callback, and that value goes on to be part of a new array returned from map that represents that item. You can think of it as a transformation from one array to another -- both with the same length -- but with each item replaced with something of your choosing, calculated from each items original contents.

  • Related