Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trying to use .reduce on an object

Tags:

javascript

So I have an object that I need to sum a nested value for all the objects. My object looks like

const json = [
{
    "other_sum": "1",
    "summary": {
        "calculations": {
            "time": 10,
            "unit": 25
        },
        "updated": "2020-06-05"
    }
},
{
    "other_sum": "1",
    "summary": {
        "calculations": {
            "time": 20,
            "unit": 5
        },
        "updated": "2020-06-05"
    }
},
{
    "other_sum": "1",
    "summary": {
        "calculations": {
            "time": 5,
            "unit": 15
        },
        "updated": "2020-06-05"
    }
},
];

I need to sum all the "unit" values

I've been trying to use .reduce for this but it only works when I have 2 items in my object, onces I get a 3rd I get an error.

The rest of my code is the following:

const r = json.reduce((a, b) => a.summary.calculations.unit + b.summary.calculations.unit);
console.log(r);

Not really sure what I'm doing wrong atm.

like image 985
OCTF Avatar asked Jul 13 '20 21:07

OCTF


2 Answers

Because thats not the way reduce works. Taken from this article it works like this:

Given

arrSum = function(arr){
  return arr.reduce(function(a,b){
    return a + b
  }, 0);
}

The function that we pass as the first parameter of the reduce method receives two parameters, a and b. In this code, a is our accumulator. It will accumulate our sum as our function works. b is the current value being processed.

So basically you are trying to access "summary" in the accumulator which is only a number. Here is the working snippet:

json = [
{
    "other_sum": "1",
    "summary": {
        "calculations": {
            "time": 10,
            "unit": 25
        },
        "updated": "2020-06-05"
    }
},
{
    "other_sum": "1",
    "summary": {
        "calculations": {
            "time": 20,
            "unit": 5
        },
        "updated": "2020-06-05"
    }
},
{
    "other_sum": "1",
    "summary": {
        "calculations": {
            "time": 5,
            "unit": 15
        },
        "updated": "2020-06-05"
    }
},
];

const r = json.reduce((a, b) => a + b.summary.calculations.unit, 0);
console.log(r);
like image 195
adelriosantiago Avatar answered Sep 23 '22 02:09

adelriosantiago


The first argument to the callback passed to .reduce is the accumulator, and the value returned from each iteration becomes the accumulator for the next iteration.

Therefore, the value called on the next item is going to be a.summary.calculations.unit + b.summary.calculations.unit, and the next time around, your callback will look for the nested property a.summary.calculations.unit on that returned value, which presumably does not exist.

You may want to change it to something along the lines of:

const r = json.reduce((a, b) => a + b.summary.calculations.unit, 0);

where 0 is the initial value for your accumulator.

MDN, as always, is a good reference.

like image 30
Kai Avatar answered Sep 25 '22 02:09

Kai